fork函数和子进程
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Fork函数
函数pid_t fork(void)
正确返回:在父进程中返回子进程的进程号,在子进程中返回0
错误返回:-1
子进程是父进程的一个拷贝。即,子进程从父进程得到了数据段和堆栈段的拷贝,这些需要分配新的内存;而对于只读的代码段,通常使用共享内存的方式访问。fork返回后,子进程和父进程都从调用fork函数的下一条语句开始执行。父进程与子进程的不同之处在于:fork的返回值不同——父进程中的返回值为子进程的进程号,而子进程为0。
以下是fork的两个示例程序:
//fork.c
#include
#include
void main ()
{
int pid;
//printf("Process [%d] begin",getpid()); //print twice
printf("Process [%d] begin\n",getpid()); //print once
//由于fork时pc等值的拷贝,子进程只会从fork处开始执行
pid = fork();
if (pid < 0)
printf("error in fork!");
else if (pid == 0)
printf("I'm child process, my pid is %d\n", getpid());
else
printf("I'm parent process, my pid is %d\n", getpid());
printf("Process [%d] end\n",getpid());
return;
}
输出结果:
使用printf("Process [%d] begin\n",getpid())时
Process [11155] begin
I'm parent process, my pid is 11155
Process [11155] end
I'm child process, my pid is 11156
Process [11156] end
使用printf("Process [%d] begin",getpid())时
Process [11054] beginI'm parent process, my pid is 11054
Process [11054] end
Process [11054] beginI'm child process, my pid is 11055
Process [11055] end
不同的输出结果是因为Printf的缓冲机制。printf某些内容时,操作系统仅仅是把该内容放到stdout的缓冲队列里,并没有实际写到屏幕上。但是,只要看到有"\n"则会立即刷新stdout,因此就马上能够打印了。运行了printf("string") 后,string 仅仅被放到了缓冲里,再运行到fork时,缓冲里的string 被子进程继承了,因此在子进程度stdout缓冲里面就也有了string。而运行printf("string\n")后,string 被立即打印到了屏幕上,之后fork到的子进程里的stdout缓冲里不会有string 内容。实际上,fork语句之前的指令在子进程中不会再执行。
//son_2_father.c
#include
#include
int main()
{
int i;
printf("Process\t[%d] begin\n",getpid());
for( i = 0; i < 3; i++)
{
int pid = fork();
if(pid == 0)
printf("son\t[%d] create [%d]\n", getpid(), pid);
else
printf("father\t[%d] create [%d]\n", getpid(), pid);
}
printf("Process\t[%d] finish\n",getpid());
return 0;
}
输出结果如下:
Process [10026] begin
father [10026] create [10027]
son [10027] create [0]
father [10026] create [10028]
father [10027] create [10029]
father [10026] create [10030]
Process [10026] finish
father [10027] create [10031]
Process [10027] finish
son [10028] create [0]
father [10028] create [10032]
Process [10028] finish
son [10032] create [0]
Process [10032] finish
son [10030] create [0]
Process [10030] finish
son [10031] create [0]
son [10029] create [0]
Process [10031] finish
father [10029] create [10033]
Process [10029] finish
son [10033] create [0]
Process [10033] finish
我们可以将此进程的执行过程表示为上图,子进程fork返回0,但是fork之后便成为了父进程,再次fork就可以得到子进程。最后,需要注意,派生子进程的进程,即父进程,其pid不变,fork之后父子进程除非采用了同步手段,否则不能确定谁先运行,也不能确定谁先结束。
参考文献:
/guichen83/article/details/4160697
/blog/static/18056918120113134516506/