fork - create a child process
#include <unistd.h>
pid_t fork(void);
//Returns:0 in child, process ID of child in parent, -1 on error
该函数返回了两次
子进程中通过getppid可以获得父进程的process ID。
父进程中通过fork返回值获得子进程process ID。
父子进程会继续执行fork之后的指令。
父子进程的堆栈和数据空间
- 子进程复制了父进程的数据空间,栈,堆。
- 共享
text segment
copy on write(COW)
自从fork经常接着调用exec,当前很多实现不执行完整的父数据,栈,堆的复制。这些区域是父子进程以read-only方式共享的。在需要修改这些区域的时候,kernel会以page进行复制。
Linux中clone(2)也能创建新进程
允许调用者控制父子进程共享什么内容
Example:
#include <stdio.h>
#include <unistd.h>
int glob = 6;
int main(void)
{
int var;
pid_t pid;
var = 88;
printf("before fork\n");
if((pid = fork()) < 0)
{
fprintf(stderr, "fork error!\n");
exit(-1);
}else if(pid == 0)//子进程
{
var++;
glob++;
}
else//父进程
{
sleep(2);
}
printf("pid = %d, glob = %d, var = %d\n", getpid(), glob, var);
exit(0);
}
结果
$./fork
before fork
pid = 3306, glob = 7, var = 89
pid = 3305, glob = 6, var = 88
$./fork > temp.out
cat temp.out
before fork
pid = 3306, glob = 7, var = 89
before fork
pid = 3305, glob = 6, var = 88
我们可以发现
第一种情况:我们只有一份printf打印的before fork
第二种情况:在fork之前,printf的数据被打印出来。此时,数据保存在缓冲区中,在调用fork之后,也被复制了一份。接下来调用的printf刷新了缓冲区
before fork
pid = 3305, glob = 6, var = 88
就被存到了文件中。
本文详细介绍了fork函数的功能与使用方法,包括其返回值的意义、父子进程间的数据共享机制以及copy-on-write技术的应用。并通过一个示例程序展示了如何利用fork创建子进程,并分析了不同情况下输出结果的差异。
1143

被折叠的 条评论
为什么被折叠?



