原创文章,转载请注明: 转载自庆亮的博客-webgame架构
本文链接地址: linux下fork函数的一些理解
fork函数用于linux下创建进程, fork的字面意思为"叉子", 从之后的内容中将会了解到"叉子"是非常的贴切的.
fork原型为 pid_t fork() , 如果成功则返回子进程的进程id, 如果失败则返回-1, 通常在系统内存不够或者进程数已经达到上限时, fork才会失败.
让我们来看一段代码
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
pid_t child;
if ((child = fork() == -1)
{
printf("fork error: %s\n", strerr(errno));
}
else if (child == 0)
{
printf("I am child : %ld \n", getpid());
}
else
{
printf("I am parent : %ld", getpid());
}
return 0;
}
先来看程序执行的结果:
[root@localhost fork]# ./main
I am child: 5731
I am parent : 5730
刚开始时, 我实在无法理解为什么可以运行if的两个分支.
仔细想想fork的作用: 创建进程 — 从父进程的此处开始复制执行.
当执行child = fork() 时, 如果返回的是-1,也就是fork失败时, 则只输出fork错误信息. 但是如果成功的创建了进程, 那么从 child = fork() 开始的代码都将会被子进程继承, 一并继承的还有子进程的数据(除了文件锁, 未决信号集以及pid, ppid). 从而子进程也会执行if ((child = fork() == -1) 这一句, 并进行if判断, fork函数在子进程中调用时会返回0 , 以表示自己是一个子进程.
到这里大家应该明白为什么会输出if的两个分支了, 因为这是两个进程执行的结果.
另外, fork函数在子进程中只是第一次运行时才会返回0 以表示自己的子进程身份, 而当第二次甚至更多次运行时则会创建新的属于自己的子进程. 来看下面的代码:
(引用自http://www.cppblog.com/zhangxu/archive/2009/02/21/37640.html)
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i = 0;
for (i=0; i<3; i++)
{
pid_t child = fork();
if (child == 0)
{
printf("child\n");
}
else if (child > 0)
{
printf("parent\n");
}
}
return 0;
}
输出的结果有7个father和7个child, 为什么呢? 第一次运行时, 产生一个子进程, 该子进程输出child, 并且自父进程获得i=0 , 子进程继续运行到for之后则i=1, 因而该子进程可以进行两次for循环, 依次类推即可得出结果. (通过图形理解比较容易.见上述链接)
0 Comments.