进程创建fork()
#include <unistd.h>
pid_t fork(void)
功能:创建子进程
fork的奇妙之处在于它被调用一次,却返回两次,它可能有三种不同的返回值:
1、在父进程中,fork返回新创建的子进程的PID;
2、在子进程中,fork返回0;
3、如果出现错误,fork返回一个负值
关于fork()的几点说明 :
1.当fork()顺利完成任务时,就会存在两个进程,每个进程都从fork()返回处开始继续执行。
2.两个进程执行相同的代码(text)段,但是有各自的堆栈(stack)段、数据(data)段以及堆(heap)。
3.子进程的stack、data、heap segments是从父进程拷贝过来的。
4.fork()之后,哪一个进程先执行(scheduled to use the CPU)不确定。但是由于子进程创建好后通常会被其他程序占用不需要使用父进程资源。为了减少子进程对父进程的复制,通常情况下程序先进入子进程运行。
vfork
#include<unistd.h>
pid_t vfork(void);
vfork函数创建的新进程,刚开始时会暂时与父进程共享地址空间。另外,vfork函数保证子进程先运行,在它调用exit之后父进程才可能被调度运行。
区别:1. fork:子进程拷贝父进程的数据段
vfork:子进程与父进程共享数据段
2. fork:父、子进程的执行次序不确定
vfork:子进程先运行,父进程后运行
wait与waitpid
#include <sys/wait.h>
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);
返回值:若成功返回进程ID,若出错返回-1。
调用wait或waitpid的进程可能发生的情况有:
如果所有子进程都还在运行,则阻塞(Block)。
如果一个子进程已终止,正等待父进程获取其终止状态,则取得该子进程的终止状态立即返回。(僵尸进程的处理)
如果它没有任何子进程,则立即出错返回。
在一个子进程终止前,wait使其调用者阻塞,而waitpid有一个选项,可使调用者不阻塞。
waitpid并不等待在其调用之后的第一个终止的子进程。它有若干个选项,可以控制它所等待的进程。
如果一个子进程已经终止,并且是一个僵尸进程,wait立即返回并取得该子进程的状态status,否则wait使其调用者阻塞直到一个子进程终止。如果调用者阻塞并且它有多个子进程,则在其一个子进程终止时,wait就立即返回。因为wait返回终止子进程的ID,所以总能了解到是哪一个子进程终止了。