1、wait和waitpid出现的原因

SIGCHLD

q  当子进程退出的时候,内核会向父进程发送SIGCHLD信号,子进程的退出是个异步事件(子进程可以在父进程运行的任何时刻终止)

q  子进程退出时,内核将子进程置为僵尸状态,这个进程称为僵尸进程,它只保留最小的一些内核数据结构,以便父进程查询子进程的退出状态。

父进程查询子进程的退出状态可以用wait/waitpid函数

2、wait和waitpid函数用法

Wait

q  头文件<sys/types.h>和<sys/wait.h>

q  函数功能:当我们用fork启动一个进程时,子进程就有了自己的生命,并将独立地运行。有时,我们需要知道某个子进程是否已经结束了,我们可以通过wait安排父进程在子进程结束之后。

q  函数原型

q  pid_t wait(int *status)

q  函数参数

q  status:该参数可以获得你等待子进程的信息

q  返回值:

q  成功等待子进程函数返回,返回值是等待子进程的ID

q  wait系统调用会使父进程暂停执行,直到它的一个子进程结束为止。

q  返回的是子进程的PID,它通常是结束的子进程

q  状态信息允许父进程判定子进程的退出状态,即从子进程的main函数返回的值或子进程中exit语句的退出码。

q  如果status不是一个空指针,状态信息将被写入它指向的位置

Wait获取status后检测处理

宏定义     描述

WIFEXITED(status)  如果子进程正常结束,返回一个非零值

WEXITSTATUS(status)      如果WIFEXITED非零,返回子进程退出码

WIFSIGNALED(status)     子进程因为捕获信号而终止,返回非零值

WTERMSIG(status) 如果WIFSIGNALED非零,返回信号代码

WIFSTOPPED(status)       如果子进程被暂停,返回一个非零值

WSTOPSIG(status)   如果WIFSTOPPED非零,返回一个信号代码

Waitpid

q函数功能:用来等待某个特定进程的结束

q函数原型:

pid_t waitpid(pid_t pid, int *status,int options)

q参数:

q  status:如果不是空,会把状态信息写到它指向的位置

qoptions:允许改变waitpid的行为,最有用的一个选项是WNOHANG,它的作用是防止waitpid把调用者的执行挂起

q  返回值:如果成功返回等待子进程的ID,失败返回-1

对于waitpid的p I d参数的解释与其值有关:

pid == -1 等待任一子进程。于是在这一功能方面waitpid与wait等效。

pid > 0 等待其进程I D与p I d相等的子进程。

pid == 0 等待其组I D等于调用进程的组I D的任一子进程。换句话说是与调用者进程同在一个组的进程。

pid < -1 等待其组I D等于p I d的绝对值的任一子进程。

3、wait pk waitpid

Wait和waitpid区别和联系

q  在一个子进程终止前, wait 使其调用者阻塞,而waitpid 有一选择项,可使调用者不阻塞。

q  waitpid并不等待第一个终止的子进程—它有若干个选择项,可以控制它所等待的特定进程。

q  实际上wait函数是waitpid函数的一个特例。

僵尸进程

q  当一个子进程结束运行时,它与其父进程之间的关联还会保持到父进程也正常地结束运行或者父进程调用了wait才告终止。

进程表中代表子进程的数据项是不会立刻释放的,虽然不再活跃了,可子进程还停留在系统里,因为它的退出码还需要保存起来以备父进程中后续的wait调用使用。它将称为一个“僵进程”

如何避免僵尸进程

q  调用wait或者waitpid函数查询子进程退出状态,此方法父进程会被挂起。

q  如果不想让父进程挂起,可以在父进程中加入一条语句:signal(SIGCHLD,SIG_IGN);表示父进程忽略SIGCHLD信号,该信号是子进程退出的时候向父进程发送的。

#include <sys/types.h>
#include <unistd.h>
#include "errno.h" #include "stdio.h"
#include "stdlib.h"
#include "string.h" #include <sys/types.h>
#include <sys/wait.h> void LoopFunc(int num)
{
printf("LoopFunc() %d....\n", num);
} int main(void )
{ int i , j = ; printf("hello...\n"); int procNum = ;
int loopNum = ;
printf("\n请输入要运行的进程数");
scanf("%d", &procNum); printf("\n请输入每个进程运行圈数");
scanf("%d", &loopNum); pid_t pid;
printf("befor fork pid:%d\n", getpid()); //fork 子进程 for (i=; i<procNum; i++)
{ pid = fork();
if (pid == -)
{
//On failure, a -1 will be retur
//errno
perror("fork err");
return ;
} if (pid == )
{
for (j=; j<loopNum; j++)
{
LoopFunc(j);
}
exit(); //让子进程跑圈 子进程不参与下一次的fork }
if (pid > ) //大于0是父进程
{
; }
} //退出
printf("after fork \n");
int mypid ; while( (mypid = waitpid(-, NULL, WNOHANG)) > )
{
printf("孩子死掉:%d\n ", mypid);
}return ; }
 
 
 
 
 

[学习笔记]父进程wait和waitpid的更多相关文章

  1. Linux内核学习笔记-2.进程管理

    原创文章,转载请注明:Linux内核学习笔记-2.进程管理) By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...

  2. Linux内核学习笔记二——进程

    Linux内核学习笔记二——进程   一 进程与线程 进程就是处于执行期的程序,包含了独立地址空间,多个执行线程等资源. 线程是进程中活动的对象,每个线程都拥有独立的程序计数器.进程栈和一组进程寄存器 ...

  3. Linux学习笔记(六) 进程管理

    1.进程基础 当输入一个命令时,shell 会同时启动一个进程,这种任务与进程分离的方式是 Linux 系统上重要的概念 每个执行的任务都称为进程,在每个进程启动时,系统都会给它指定一个唯一的 ID, ...

  4. Linux C语言编程学习笔记 (1)进程控制入门

    想进行Linux系统开发已经很久了,一直没有付诸实践.今日终于开始学习Linux下的C语言编程,研究一天,终于大概弄明白了Linux系统进程管理的一些基本概念和编程方法,总结下来以方便大家学习和自己实 ...

  5. RHCA学习笔记:RH442-Unit8进程与调度

      UNIT 8  Processes and the Scheduler 进程与调度 学习目标 A. CPU cache 与Service time之间的关系 B. 分析应用程序使用CPU cach ...

  6. linux学习笔记之进程

    一.基础知识 1:进程. 1,进程ID: 非负整数,具有唯一性. 1)ID=0的进程:调度进程/交换进程.内核的一部分.不执行任何磁盘上的程序. 2)ID=1的进程:init进程. 1-自举结束时,由 ...

  7. Linux System Programming 学习笔记(五) 进程管理

    1. 进程是unix系统中两个最重要的基础抽象之一(另一个是文件) A process is a running program A thread is the unit of activity in ...

  8. APUE 学习笔记(六) 进程控制

    1. fork 创建新进程 fork创建的新进程称为子进程,fork函数调用一次,返回两次. 两次返回的唯一区别就是子进程的返回值是0,而父进程的返回值是新子进程的进程ID 在fork之后是父进程先执 ...

  9. python 学习笔记八 进程和线程 (进阶篇)

    什么是线程(thread)? 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执 ...

随机推荐

  1. Tomcat 优化方案 和 配置详解

    转载: http://blog.csdn.net/yi2672379417/article/details/51442229

  2. Linux下anaconda的安装

    http://peteryuan.net/use-anaconda/ http://www.jianshu.com/p/03d757283339

  3. qduoj su003 数组合并

    描述 现在呢有两个整形数组,a[n]和b[m],而且已经知道这两个数组都是非降序数组.现在呢就有一个工作需要你来完成啦.对于a中的每个元素a[i]在b中寻找<=a[i] 的元素个数,个数记为x[ ...

  4. Vue forms

    Vue forms Vue 的表单. 表单中的数据和是双向绑定的. 你可以使用 v-model 对控件元素进行数据双向绑定. 比较有用的修饰符 .lazy .number .trim

  5. angular +H5 上传图片 与预览图片

    //index.html <form class="form-horizontal"> <div class="panel panel-default& ...

  6. 前用户sudo免密码

      Ubuntu 设置当前用户sudo免密码 方法1 # 备份 /etc/sudoers sudo cp /etc/sudoers . #打开 /etc/sudoers sudo visudo # 在 ...

  7. linux 定时备份mysql

    定时备份:1.创建备份文件存放目录2.创建备份脚本backup.sh #!/bin/bash DBUser=db_backDBPasswd=passwordDBName=db_nameSERVER=l ...

  8. Idea编译器 报@Override错误

    据说这是jdk的问题,@Override是JDK5就已经有了,但有个小小的Bug,就是不支持对接口的实现,认为这不是Override 而JDK6修正了这个Bug,无论是对父类的方法覆盖还是对接口的实现 ...

  9. Http服务端

    第一,使用node提供的http模块 var http=require('http'); 第二,创建一个服务器实例 通过http的createServer()方法. var server=http.c ...

  10. leetcode661

    vector<vector<int>> imageSmoother(vector<vector<int>>& M) { ; vector< ...