Unix环境高级编程:fork, vfork, clone
fork
fork产生的子进程是传统意义上的进程,fork之后执行路径就互不关联了,一旦fork返回后面的代码就在不用的进程上下文中执行了。到底是子进程先执行还是父进程先执行一般是随机的或者依赖实现的。
vfork
vfork使得“子进程”先于“父进程”执行,子进程在父进程的进程空间中执行直到其调用exec。vfork的使用还是要相对小心的,vfork最摸个作用域内调用时,在子进程执行的时候,如果父进程将来会使用到该作用域内的变量,则子进程不能使用return语句退出当前函数框架。如下面的代码:
#include <stdio.h>
#include <unistd.h>
pid_t invoke_vfork() {
int count = 0;
pid_t pid = vfork();
if (pid == 0) {
while (++count < 10000);
} else {
printf("count value %u\n", count);
}
return pid;
}
int main() {
printf("before invoke_vfork\n");
if (invoke_vfork() == 0) {
_exit(0);
}
printf("after invoke_vfork\n");
return 0;
}
如上述的代码运行后回输出:
before invoke_vfork
count value 3560223176
after invoke_vfork
看起来还是相当诡异的,如果我们把_exit(0)直接放入到子进程那个函数分支内部则没有这个问题:
pid_t invoke_vfork() {
int count = 0;
pid_t pid = vfork();
if (pid == 0) {
while (++count < 10000);
_exit(0);
} else {
printf("count value %u\n", count);
}
return pid;
}
输出:
before invoke_vfork
count value 10000
after invoke_vfork
不过一般也不会这么使用,直接exec就没有问题了。
clone
clone是Linux平台上专有的系统调用,可以更细粒度的指定子进程与父进程共享的内容,可以用来创建LWP,也即线程。