
创建进程使用 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
父子进程特点及对比
- 调用一次,返回两次
- 并发执行
- 虽然子进程是父进程创建的,但是二者是独立并发执行的。也就是说,在一个计算机系统上,父进程先执行 Printf 打印,然后是子进程执行。然而在其他的系统上运行相同的程序时,很可能会得到相反的结果。所以,究竟是父进程先执行打印还是子进程先执行打印,对于不同的系统很可能是不同的
- 相同但是独立的地址空间
- 当父进程调用 Fork 函数创建子进程后,如果我们立刻暂停程序继续执行,也就是说,不等的函数 fork 返回到父进程和子进程之前就执行一个暂停的操作。此时,父进程与子进程的地址空间中的内容是相同的,二者具有相同的用户栈、相同的本地变量值、相同的堆、相同的全局变量值以及相同的代码。
- 当 Fork 返回后,本地变量 x 在父进程和子进程中都是 1。然而父进程和子进程是独立的进程,他们都有自己的私有地址空间。后面父进程和子进程对变量 x 所做的任何改变都是独立的,不会反映到另一个进程的内存中。
- 子进程虽然复制了父进程所有的地址空间的内容,但是二者具有独立的地址空间。
- 父进程和子进程都把他们的执行结果输出到了显示屏幕上,原因是子进程继承了父进程所有打开的文件。这里的文件是指:父进程调用 Fork 函数时,标准输出文件是打开的,并指向屏幕,子进程继承了这个文件,所以它的输出也是指向屏幕的