fork函数和子进程

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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/

相关文档
最新文档