8.1.3 创建进程
Linux系统通过fork()系统调用创建一个进程,fork()函数定义如下:
#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);
fork()系统调用在应用程序库里对应一个同名的fork()函数。fork()函数的定义很简单,但是初学者会感到不好理解,应注意分析多进程环境的特点。如图8-1所示为创建进程的过程。
从图8-1中可以看出,fork()函数的作用是创建一个进程。在应用程序调用fork()函数后,会创建一个新的进程,称做子进程,原来的进程称做父进程。从这以后,运行的已经是两个进程了,子进程和父进程都可以得到fork()函数的返回值。对于子进程来说,fork()函数的返回值是0,对于父进程来说,fork()函数返回的是子进程的进程号。如果创建进程失败,fork()函数会给父进程返回–1,这也是判断进程是否创建成功的依据。
图8-1 使用fork()系统调用创建进程
fork()函数创建子进程后,会复制父进程的数据段、代码段和堆栈空间等到子进程的空间。同时,子进程会共享父进程中打开的文件。换句话说,父进程已经打开的文件,在子进程中可以直接操作。实例8-2演示了创建进程的过程。
实例8-2 创建进程演示
1 #include <sys/types.h>
2 #include <unistd.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5
6 int main()
7 {
8 pid_t pid;
9
10 pid = fork(); // 创建进程
11 if (-1==pid) { // 创建进程失败
12 printf("Error to create new process!/n");
13 return 0;
14 }
15 else if (pid==0) { // 子进程
16 printf("Child process!/n");
17 } else { // 父进程
18 printf("Parent process! Child process ID: %d/n", pid);
19 }
20
21 return 0;
22 }
23
程序定义了一个pid_t类型的全局变量来存放进程号,pid_t是个预定义的类型,其实就是int类型。代码的第10行调用fork()创建进程,从第11行开始,程序已经不是一个进程了,而是被子进程和父进程执行,并且全局变量pid也被复制一份到子进程中,所以,第15行和第11行的pid值是不一样的,根据fork()函数的返回结果,程序对pid值进行了判断,并且打印出了父进程和子进程。