最近课堂上学到了这个好玩的函数,于是就真的开始玩起来了。。。
首先是这个函数的官方解说:
fork系统调用用于创建一个新进程,称为子进程,它与进程(称为系统调用fork的进程)同时运行,此进程称为父进程。创建新的子进程后,两个进程将执行fork()系统调用之后的下一条指令。子进程使用相同的pc(程序计数器),相同的CPU寄存器,在父进程中使用的相同打开文件。
关于这个,我们Linux书上有一个形象的比喻:
随着一句fork,一个新进程呱呱落地,但这时它只是老进程的一个克隆。
不过汉字文化博大精深,还是不大明白的亚子,,于是我就找了几个比较典型的例子跑了一跑:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
int main(int argc, char *argv[])
{
pid_t pid;
int x = 1;
pid = Fork();
if (pid == 0)
printf("child : x=%d\n", ++x);
fflush(stdout);
return 0;
}
printf("parent: x=%d\n", --x);
fflush(stdout);
return 0;
}
结果如下:
这个时候就变得好玩了。
可见fork被调用一次,却能够返回两次。根据老师的说法,fork可能有三种不同的返回值:
1.在父进程中,fork返回新创建子进程的进程ID;
2.在子进程中,fork返回0;
3.如果出现错误,fork返回一个负值;
两次是能理解了,但结果呢?于是我又翻了一下另一堂课的书,结合老师的说法,得出了这样的结论:
fork的作用是复制一个进程,两个进程是并发执行的,而且Linux是使用写时复制来实现fork的。那么其实这两个进程其实可以分开来看,各干各的,只是初始值一样而已。大致是这样:
这样就很好理解了吧!
后面我又跑了几个其他fork函数,代码和结果如下:
void fork0()
{
if (fork() == 0) {
printf("Hello from child\n");
}
else {
printf("Hello from parent\n");
}
}
void fork1()
{
int x = 1;
pid_t pid = fork();
if (pid == 0) {
printf("Child has x = %d\n", ++x);
}
else {
printf("Parent has x = %d\n", --x);
}
printf("Bye from process %d with x = %d\n", getpid(), x);
}
void fork2()
{
printf("L0\n");
fork();
printf("L1\n");
fork();
printf("Bye\n");
}
注意fork2这个函数我放出的两个运行结果不一样,原因就是我刚刚说的“两个进程并发执行”,注意“复制”和“并发”两个关键字,是fork最基本的要点,如果有很难分清的情况,就可以像我琢磨第一个代码一样画一个能分清的图。。。
不过我这是跑了最基础且典型的代码,不够深层,这位前辈的会更深层哦~
https://blog.csdn.net/jason314/article/details/5640969