对于进程的一生可以用一些形象的比喻作一个小小的总结:
随着一句fork,一个新进程呱呱落地,但它这时只是老进程的一个克隆。
然后随着exec,新进程脱胎换骨,离家独立,开始了为人民服务的职业生涯。
人有生老病死,进程也一样,它可以是自然死亡,即运行到main函数的最后一个”}”,从容地离我们而去;也可以是自杀,自杀有2种方式,一种是调用 exit函数,一种是在main函数内使用return,无论哪一种方式,它都可以留下遗书,放在返回值里保留下来;它还甚至能可被谋杀,被其它进程通过另外一些方式结束他的生命。
进程死掉以后,会留下一具僵尸,wait和waitpid充当了殓尸工,把僵尸推去火化,使其最终归于无形。
在linux中wait系统调用一文中介绍了其中的一个殓尸工wait, 下面介绍另一个waitpid,这个貌似复杂些。
waitpid函数原型:
#include<sys/types.h>/* 提供类型pid_t的定义 */
#include<sys/wait.h>
pid_twaitpid(pid_tpid,int*status,intoptions);
从本质上讲,系统调用waitpid和wait的作用是完全相同的,但waitpid多出了两个可由用户控制的参数pid和options,从而为我们编程提供了另一种更灵活的方式。下面我们就来详细介绍一下这两个参数:
pid
从参数的名字pid和类型pid_t中就可以看出,这里需要的是一个进程ID。但当pid取不同的值时,在这里有不同的意义。
1. pid>0时,只等待进程ID等于pid的子进程,不管其它已经有多少子进程运行结束退出了,只要指定的子进程还没有结束,waitpid就会一直等下去。
2. pid=-1时,等待任何一个子进程退出,没有任何限制,此时waitpid和wait的作用一模一样。
3. pid=0时,等待同一个进程组中的任何子进程,如果子进程已经加入了别的进程组,waitpid不会对它做任何理睬。
4. pid<-1时,等待一个指定进程组中的任何子进程,这个进程组的ID等于pid的绝对值。
options
options提供了一些额外的选项来控制waitpid,目前在Linux中只支持WNOHANG和WUNTRACED两个选项,这是两个常数,可以用”|”运算符把它们连接起来使用,比如:
ret=waitpid(-1,NULL,WNOHANG|WUNTRACED);
如果我们不想使用它们,也可以把options设为0,如:
ret=waitpid(-1,NULL,0);
如果使用了WNOHANG参数调用waitpid,即使没有子进程退出,它也会立即返回,不会像wait那样永远等下去。
而WUNTRACED参数,用于跟踪调试,极少用到,就不说了。
查看linux源代码 unistd.h 我们会发现,其实 wait 就是经过包装的 waitpid:
staticinlinepid_twait(int*wait_stat)
{
returnwaitpid(-1,wait_stat,0);
}
waitpid的返回值比wait稍微复杂一些,一共有3种情况:
1. 当正常返回的时候,waitpid返回收集到的子进程的进程ID;
2. 如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;
3. 如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在;
当pid所指示的子进程不存在,或此进程存在,但不是调用进程的子进程,waitpid就会出错返回,这时errno被设置为ECHILD;
下面看一个简单的例子:
下载:waitpid.c
/* waitpid.c */
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<stdio.h>
int main()
{
pid_t pc,pr;
pc=fork();
if (pc<0)/* fork错误*/
{
printf("fork error\n");
exit(1);
}
else if(pc==0)/*在子进程中*/
{
sleep(10);
exit(0);
}
else
{
do {/* 使用了WNOHANG参数,waitpid不会在这里等待 */
pr=waitpid(pc,NULL,WNOHANG);
if (pr==0)
{
printf("No child exit\n");
sleep(1);
}
}while (pr==0);
if (pr==pc)
printf("successfully get child %d\n",pr);
else
printf("wait child error\n");
}
return 0;
}
编译并运行:
$ gcc -o waitpid waitpid.c
$ ./waitpid
No child exit
No child exit
No child exit
No child exit
No child exit
No child exit
No child exit
No child exit
No child exit
No child exit
successfully get child 4607
父进程经过10次失败的尝试之后,终于收集到了退出的子进程。父进程和子进程分别睡眠了10秒钟和1秒钟,代表它们分别作了10秒钟和1秒钟的工作。父子进程都有工作要做,父进程利用工作的简短间歇察看子进程的是否退出,如退出就收集它。

linux进程(fork,waitpid)相关推荐

  1. linux waitpid 用法,linux的fork(),waitpid()及wait()的用法

    这个是作业!更新写在前面! 试了下一个小程序: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 2 ...

  2. linux进程--fork详解(三)

    1.fork 首先我们先来回忆一下fork()函数: 函数头文件:#include<unistd.h> 函数原型:pid_t fork(void);其中pid_t是一个宏定义:#defin ...

  3. linux进程--fork详解(二)

    一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同, ...

  4. 剖析Linux进程forkvforkclone原理机制丨进程管理指令及监控工具

    剖析Linux进程fork&vfork&clone原理机制丨进程管理指令及监控工具 视频讲解如下,点击观看: 剖析Linux进程fork&vfork&clone原理机制 ...

  5. Linux进程创建fork、进程退出exit()、进程等待waitpid()

    虽然通过标题,我们就轻易的知道了这三个函数的作用,可是,你真的了解这几个函数码?下面让我们来看看这三个函数到底有什么! 一.进程创建fork() 首先,我们来看一看fork()的函数声明: #incl ...

  6. Linux进程相关,fork,wait,waitpid,WIFEXITED

    fork 我们可以通过调用fork创建一个新进程.这个系统调用复制当前进程,在进程表中创建一个新的表项,新表项中的许多属性与当前进程是相同的.新进程几乎与原进程一模一样,执行的代码也完全相同,但新进程 ...

  7. linux 创建子进程,linux中fork同时创建多个子进程的方法(一)

    Fork同时创建多个子进程方法 第一种方法:验证通过 特点:同时创建多个子进程,每个子进程可以执行不同的任务,程序 可读性较好,便于分析,易扩展为多个子进程 int main(void) { prin ...

  8. 【Linux进程、线程、任务调度】二 fork/vfork与写时拷贝 线程的本质 托孤 进程睡眠和等待队列

    学习交流加(可免费帮忙下载CSDN资源): 个人微信: liu1126137994 学习交流资源分享qq群1(已满): 962535112 学习交流资源分享qq群2(已满): 780902027 学习 ...

  9. linux 进程等待 wait 、 waitpid

    waitpid() 与 wait() 功能相似,都是用户主进程等待子进程结束或中断. 可用于进程之间的同步 wait 函数原型 pid_t wait(int *status); 函数说明 wait() ...

  10. linux进程管理fork,Linux -- 进程管理之 fork() 函数

    一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间.然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同.相当于克隆了一个自己. Test1 f ...

最新文章

  1. stm32 输出PWM
  2. Java多线程之线程间协作 notify与wait的使用
  3. 信息系统项目管理知识--信息系统建设
  4. Python冒泡排序(4)
  5. java线程唤醒与等待_Java线程的等待与唤醒
  6. 小米5点位图_最新!地铁5号线、6号线部分车站文化墙设计出炉!你选哪个?
  7. python代码300行程序_python小工具,15行代码秒出工资条
  8. raspberry pi_什么是Raspberry Pi基金会? 售出1000万台计算机
  9. php element 插件_为phpstorm安装vue插件
  10. [转载]Qt之自定义界面(二)添加最小化、关闭按钮、添加背景_vortex_新浪博客...
  11. Linux的diff和git diff生成patch/打patch
  12. 计算机组成原理概述篇
  13. 植物大战僵尸无尽模式最强阵容可以无限打
  14. JS脚本实现浏览器自动点击(阿里员工秒杀月饼)
  15. kodi没有中文设置_超详细带你解决KODI找不到中文的问题(XB0X ONE/安卓通用)
  16. 第五章第二十八题(显示每月第一天是星期几)(Display the first days of each month)
  17. flex弹性盒子(伸缩盒模型)的使用
  18. phpwind mysql 密码_PhpWind教程:MySQL数据库密码修改方法
  19. 中专计算机教研组活动总结,教研活动总结(精选6篇)
  20. 中国IT成功人士特点6大成功密码全解析

热门文章

  1. [古怪问题] Marshal.GetActiveObject 在管理员模式下无法正常运行
  2. Django实例-静态访问
  3. 【Javascript第二重境界】序
  4. 安装php的mongodb扩展
  5. 写给我--过去,现在,未来
  6. Mac 识别NTFS移动硬盘
  7. make it clear how to use const in C++
  8. 谷歌推出关于滥用研究资助的新型试验计划
  9. JavaScript人脸检测的实现方法
  10. 指针4-指针的运算和指针变量占几个字节