UNIX之fork与vfork函数

一、fork函数

1、每个进程都有一个非负整数表示的唯一进程ID,进程ID是可复用的;

  • ID为0的进程通常是调度进程,被称为交换进程(swapper),属于内核的一部分,并不执行任何磁盘上的程序,也被成为系统进程;
  • ID为1的进程通常是init进程,init通常读取与系统有关的初始化文件。init进程绝不会终止,他是一个普通的用户进程,但是可以超级用户特权运行。
  • ID为2的是页守护进程,负责支持虚拟存储器系统的分页操作。

2、一个现有的进程可以调用fork函数创建一个新进程。

#include <unistd.h>
pid_t fork(void);

//返回值:子进程返回0,父进程返回子进程ID,若出错,则返回-1;

由fork创建的新进程被称为子进程(child process),fork函数被调用一次,但返回两次。两次返回的区别是子进程的返回值是0,而父进程的返回值是新建子进程的进程ID。

  • fork使子进程得到返回值0,理由:

一个进程只会有一个父进程,所以子进程总是可以调用getppid以获得其父进程的进程ID(进程ID0总是由内核交换进程使用,所以一个子进程的进程ID不可能为0)。

  • 子进程ID为什么要返回给父进程?

一个进程的子进程可以有多个,并且没有一个函数使一个进程可以获得其所有子进程的进程ID。

经过GCC之后,

可以看出子进程的变量值改变,子进程ID是9111,父进程ID为9110.

3、fork的两种用法

(1)一个父进程希望复制自己,使父进程和子进程同时执行不同的代码段。

比如在网络服务进程中,父进程等待客户端的服务请求,当这种请求到达时,父进程调用fork,使子进程处理此请求,父进程则继续等待下一个服务请求。

(2)一个进程要执行不同的程序

shell中常见,子进程调用fork返回后立即调用exec。

二、vfork函数

vfork函数用于创建一个新进程,而该新进程的目的是exec一个新程序。

vfork与fork都是创建一个子进程,但是它并不将父进程的地址空间完全复制到子进程中,因为子进程会立即调用exec或者exit,于是也就不会引用该地址空间,不过在子进程调用exec或exit之前,他在父进程的空间中运行。

vfork保证子进程先运行,在它调用exec或exit之后父进程才可能被调度运行,当子进程调用这两个函数中的任意一个时,父进程会恢复运行。(如果在调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁)。

参考《UNIX环境高级编程》第三版。

猜你喜欢

转载自blog.csdn.net/qq_32164245/article/details/81071431