1. 首页
  2. 操作系统
  3. Unix
  4. fork函数-鸿鹄论坛_华为认证h35-211-hcnp-access network题库

fork函数-鸿鹄论坛_华为认证h35-211-hcnp-access network题库

上传者: 2024-07-15 20:49:48上传 PDF文件 18.16MB 热度 9次

8.3 fork函数

一个现存进程调用fork函数是UNIX内核创建一个新进程的唯一方法(这并不适用于前节提及的交换进程、init进程和页精灵进程。这些进程是由内核作为自举过程的一部分以特殊方式创建的)。


#include <sys types.h="">

#include <unistd.h>

pid_t fork(void);

unistd.h>sys>

返回:子进程中为0,父进程中为子进程ID,出错为-1。

由fork创建的新进程被称为子进程(child process)。该函数被调用一次,但返回两次。两次返回的区别是子进程的返回值是0,而父进程的返回值则是新子进程的进程ID。将子进程ID返回给父进程的理由是:因为一个进程的子进程可以多于一个,所以没有一个函数使一个进程可以获得其所有子进程的进程ID。fork使子进程得到返回值0的理由是:一个进程只会有一个父进程,所以子进程总是可以调用getppid以获得其父进程的进程ID(进程ID 0总是由交换进程使用,所以一个子进程的进程ID不可能为0 )。

子进程和父进程继续执行fork之后的指令。子进程是父进程的复制品。例如,子进程获得父进程数据空间、堆和栈的复制品。注意,这是子进程所拥有的拷贝。父、子进程并不共享这些存储空间部分。如果正文段是只读的,则父、子进程共享正文段。现在很多的实现并不做一个父进程数据段和堆的完全拷贝,因为在fork之后经常跟随着exec。作为替代,使用了在写时复制(Copy-On-Write, COW)的技术。这些区域由父、子进程共享,而且内核将它们的存取许可权改变为只读的。如果有进程试图修改这些区域,则内核为有关部分,典型的是虚存系统中的“页”,做一个拷贝。

Bach〔1986〕的9.2节和Leffler等〔1989〕的5.7节对这种特征做了更详细的说明。实例程序8-1例示了fork函数。如果执行此程序则得到:


$ a.out

a write to stdout before fork

pid = 430, glob = 7, var = 89

子进程的变量值改变了:


pid = 429, glob = 6, var = 88

父进程的变量值没有改变:


$ a.out > temp.out

$ cat temp.out

a write to stdout before fork

pid = 432, glob = 7, var = 89

before fork pid = 431, glob = 6, var = 88

一般来说,在fork之后是父进程先执行还是子进程先执行是不确定的。这取决于内核所使用的调度算法。如果要求父、子进程之间相互同步,则要求某种形式的进程间通信。在程序8-1中,父进程使自己睡眠2秒钟,以此使子进程先执行。但并不保证2秒钟已经足够,在8.8节说明竟争条件时,还将谈及这一问题及其他类型的同步方法。在10.6节中,在fork之后将用信号使父进程同步。

相关链接:

用户评论