本文将记录我在学习fork和wait(waitpid)这两个函数的过程。
1.fork
在linux中,创建一个新进程常用fork函数,它非常特别,执行一次,居然返回两个值,这与一般的函数是大大的不一样的,这点引起了我高度的注意。
prototype: pid_t fork(void)
return: 0 ——子进程
>0(即子进程ID)——父进程
-1 ——出错
接下来继续介绍wait函数,最后再给出例程实践。
2.wait
wait函数用于使父进程阻塞,直到一个子进程结束或者进程接到了一个指定的信号为止。若父进程没有子进程或者子进程已结束,则wait就会立即返回。
prototype : pid_t wait(int *status)
parameter: status是该子进程退出时的状态,若为NULL,则代表任意状态结束子进程。若不为空,则代表指定状态结束子进程。
return : 子进程id号 —— success
-1 —— failure
fork和wait的使用范例如下
int main(void)
{
pid_t pc, pr;
pc = fork();
if (0 == pc) //进入子进程
{
printf("i`m child process with pid of %d/n", getpid());
sleep(10); //睡眠10s
}
else if (pc > 0) //进入父进程
{
pr = wait(NULL); //等待子进程结束,并取得子进程id
printf("i catch child process with pid of %d/n", pr);
}
return 0;
}
程序解释:pc = fork();这一句创建了一个新的子进程,根据返回的值来进行判断将要执行的是父进程还是子进程。fork()与vfork()不一样,创建子进程之后,接着调用的是父进程还是子进程是随机的,具体关于fork和vfork的介绍请看http://blog.csdn.net/jarvis_xian/archive/2011/05/11/6412658.aspx
既然执行父进程或者子进程的先后是随机的,那上述例程分两种情况论述。
1.先执行子进程
程序自上而下运行,子进程打印语句后,睡眠10s,父进程接管,等待子进程结束(睡眠结束即子进程结束),获取结束的子进程的pid,接着打印出来。
2.先执行父进程
父进程一开始就执行wait函数,因为子进程还没有结束(甚至还没有开始,但是已经存在的),所以父进程在一个阻塞的状态,既然父进程阻塞了,那就转向执行子进程了,接下来的过程就跟第一种情况一样了。
大家可以尝试编译、运行上述程序,看看效果,这对于fork和wait的作用就一目了然了。