进程创建
再识fork函数
之前在 Linux进程状态 这篇文章中,我们已经为大家介绍过Linux系统中一个非常重要的系统调用 — fork,今天我们在来重谈 fork 函数,让大家对这个系统调用有更深刻的理解。
在 Linux中 fork 函数是非常重要的函数,它从已存在进程中创建⼀个新进程。创建出来的新进程叫做子进程,而原进程则称为父进程。
在Linux参考手册中,fork函数的原型如下:(man 2 fork 指令查看)
NAME
fork - create a child process
SYNOPSIS
#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);
1
2
3
4
5
6
7
8
如上不难看出:
fork 函数的功能是创建一个子进程
头文件有 <sys/types.h> 和 <unistd.h>
参数为 void ,返回值为 pid_t (实际上是Linux内核中typedef出来的一个类型)
进程调用 fork,当控制转移到内核中的 fork 代码后,内核做如下几件事:
分配新的内存块和内核数据结构给子进程
将父进程部分数据结构内容拷贝至子进程
添加子进程到系统进程列表当中
fork返回,开始调度器调度
当⼀个进程调用fork之后,就有两个⼆进制代码相同的进程。并且它们都运行到相同的地方。但每个进程都将可以开始属于它们自己的旅程,看如下程序:
int main(void)
{
pid_t pid;
printf("Before: pid is %d\n", getpid());
if ((pid = fork()) == -1)
perror("fork()"), exit(1);
printf("After:pid is %d, fork return %d\n", getpid(), pid);
sleep(1);
return 0;
}
1
2
3
4
5
6
7
8
9
10
输出:
Before: pid is 40176
After:pid is 40176, fork return 40177
After:pid is 40177, fork return 0
1
2
3
这里看到了三行输出,⼀行before,两行after。其中 40176就是父进程啦,40177就是子进程。进程40176先打印before消息,然后它有打印after。另⼀个after消息是进程40177打印的。注意到进程40177没有打印before,为什么呢?
如下图所示:
当父进程执行到fork创建出子进程时,已经执行了上面的before代码,而创建出子进程后,子进程不会去执行父进程已经执行过的代码,而是和父进程一同执行fork之后的代码。这就是为什么子进程没有打印before的原因
所以,fork之前父进程独立执行,fork之后,父子进程两个执行流分别执行之后的代码。值得注意的是,fork之后,谁先执行完全由调度器决定,并没有明确的先后关系!
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/bite_zwy/article/details/147062981
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




