进程创建
fork函数
使用
fork函数
创建进程使用 fork 系统函数
定义如下:#include<sys/types.h> #include<unistd.h> pid_t fork(void);
pid_t作为返回类型,被定义为int
函数 fork 被调用一次却返回两次
- 一次是返回到父进程
- 另外一次是返回到新创建的子进程
看下方这个例子
#include<stdio.h> #include<sys/types.h> #include<unistd.h> #include<stdlib.h> int main() { pid_t pid; int x = 1; pid = fork(); if(pid == 0) { printf("Child:x=%d\n",++x); exit(0); } printf("Parent:x=%d\n",--x); exit(0); }进程图如下
- 父进程中,fork 函数返回子进程的进程号,所以不为 0
- 子进程中,fork 返回 0
父子进程特点及对比
Link to original
- 调用一次,返回两次
- 并发执行
- 虽然子进程是父进程创建的,但是二者是独立并发执行的。也就是说,在一个计算机系统上,父进程先执行 Printf 打印,然后是子进程执行。然而在其他的系统上运行相同的程序时,很可能会得到相反的结果。所以,究竟是父进程先执行打印还是子进程先执行打印,对于不同的系统很可能是不同的
- 相同但是独立的地址空间
- 当父进程调用 Fork 函数创建子进程后,如果我们立刻暂停程序继续执行,也就是说,不等的函数 fork 返回到父进程和子进程之前就执行一个暂停的操作。此时,父进程与子进程的地址空间中的内容是相同的,二者具有相同的用户栈、相同的本地变量值、相同的堆、相同的全局变量值以及相同的代码。
- 当 Fork 返回后,本地变量 x 在父进程和子进程中都是 1。然而父进程和子进程是独立的进程,他们都有自己的私有地址空间。后面父进程和子进程对变量 x 所做的任何改变都是独立的,不会反映到另一个进程的内存中。
- 子进程虽然复制了父进程所有的地址空间的内容,但是二者具有独立的地址空间。
- 父进程和子进程都把他们的执行结果输出到了显示屏幕上,原因是子进程继承了父进程所有打开的文件。这里的文件是指:父进程调用 Fork 函数时,标准输出文件是打开的,并指向屏幕,子进程继承了这个文件,所以它的输出也是指向屏幕的
多次调用fork
#include <stdio.h>
#include <unistd.h> // Include the necessary header file
#include <stdlib.h> // Include the necessary header file
int main(){
fork();
fork();
printf("hello\n");
exit(0);
}
//
//hello
//hello
//hello
//hello 第一个 fork 开一个子进程,+1

父进程和子进程有相同的内容,所以都接下来要执行第二个 fork,+2
这里践行的就是相同但是独立的地址空间, 遇到 fork 就重复复制一遍接下来的操作

加上原本父进程自己,就是 1+1+2,总共输出 4 次
嵌套调用fork
父进程嵌套调用fork


子进程嵌套调用fork




