forkexec之间有什么区别?

推荐答案

forkexec的使用体现了UNIX的精神,因为它提供了启动新进程的非常简单的方法.

fork调用基本上复制了当前进程,在每种情况下almost都是相同的.并非所有内容都会被复制(例如,某些实现中的资源限制),但我们的 idea 是创建尽可能接近的副本.

新进程(子进程)获得不同的进程ID(PID),并将旧进程(父进程)的PID作为其父进程PID(PPID).因为这两个进程现在正在运行完全相同的代码,所以它们可以通过返回代码fork来区分哪个是哪个-子进程得到0,父进程得到子进程的PID.当然,假设fork调用正常工作,这就是全部内容-如果不工作,则不会创建子进程,父进程将获得错误代码.

exec调用是一种基本上用新程序取代当前整个流程的方法.它将程序加载到当前进程空间,并从入口点运行.

因此,forkexec通常按顺序使用,以使新程序作为当前进程的子进程运行.每当你试图运行一个像find这样的程序时,shell通常会这样做——shellForking ,然后子程序将find程序加载到内存中,设置所有命令行参数、标准I/O等等.

但它们不需要一起使用.例如,如果程序同时包含父代码和子代码(您需要小心操作,每个实现可能都有限制),则完全可以接受程序本身为fork而不使用execing.对于只在TCP端口上侦听的守护进程来说,这已经被大量使用了(现在仍然是),而当父进程返回侦听时,守护进程将自己的一个副本用于处理特定的请求.

类似地,那些知道已经完成并且只想运行另一个程序的程序不需要为子元素设置forkexecwait.他们可以直接将子进程加载到进程空间中.

一些UNIX实现有一个优化的fork,它使用了他们所说的写时拷贝.这是一个将复制进程空间延迟到fork的技巧,直到程序试图更改该空间中的某些内容.这对于那些只使用fork而不是exec的程序很有用,因为它们不必复制整个进程空间.

如果exec is调用following fork(这是大多数情况下发生的情况),则会导致对进程空间进行写入,然后为子进程复制.

请注意,有exec个电话(execlexecleexecve等等)组成了一个完整的家庭,但这里的exec指的是其中的任何一个.

下图显示了典型的fork/exec操作,其中bash shell用于使用ls命令列出目录:

+--------+
| pid=7  |
| ppid=4 |
| bash   |
+--------+
    |
    | calls fork
    V
+--------+             +--------+
| pid=7  |    forks    | pid=22 |
| ppid=4 | ----------> | ppid=7 |
| bash   |             | bash   |
+--------+             +--------+
    |                      |
    | waits for pid 22     | calls exec to run ls
    |                      V
    |                  +--------+
    |                  | pid=22 |
    |                  | ppid=7 |
    |                  | ls     |
    V                  +--------+
+--------+                 |
| pid=7  |                 | exits
| ppid=4 | <---------------+
| bash   |
+--------+
    |
    | continues
    V

C++相关问答推荐

理解C中的指针定义

C限制限定符是否可以通过指针传递?

自定义malloc实现上奇怪的操作系统依赖行为

如何避免重新分配指针数组时,我们从一开始就不知道确切的大小

为什么在C中设置文件的位置并写入文件,填充空字符?

getchar读css + z还是返回css?

数据包未从DPDK端口传输到内核端口

将 struct 传递给函数

1处的解析器错误:yacc语法的语法错误

防止规范模式在C++中 echo 特殊字符

如何使用C++在控制台中以彩色打印被阻止的客户端

安全倒计时循环

为什么编译器不能简单地将数据从EDI转移到EAX?

`预期说明符-限定符-列表在‘(三元运算符中的’token`‘之前

`%%的sscanf无法按预期工作

使用 c 中的 write() 函数将非 ASCII 字符写入标准输出

如何为avr atmega32微控制器构建C代码,通过光电二极管捕获光强度并通过串行通信传输数据

如何向 execl 创建的后台程序提供输入?

多行表达式:C 编译器如何处理换行符?

如何正确探测平台设备?