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. 如果两个人,两台电脑同时登录同一个帐号,同时对同一个账单提交,账单同时被服务器处理,那服务器应该先处理谁的,或者怎么规避这个问题。 非单点登录,重定向,stoken拦截器的问题

    方法一:给用户设置个状态 服务器端坐标记,比如数据库中增加一列,标识是否登陆,登录时先判断这个就行了,不过要考虑非正常退出的情况 http 方法二:在用户表里面 多加一个状态字段,登录成功 改变状态  ...

  2. Communication System(动态规划)

    个人心得:百度推荐的简单DP题,自己做了下发现真得水,看了题解发现他们的思维真得比我好太多太多, 这是一段漫长的锻炼路呀. 关于这道题,我最开始用DP的思路,找子状态,发现自己根本就不会找DP状态数组 ...

  3. ProjectEuler654

    我,ycl:BM是什么早就忘了! 毕老爷:那你们可以做一做这道题练练BM板子啊. 传送门 //Achen #include<bits/stdc++.h> #define For(i,a,b ...

  4. 六、python沉淀之路--int str list tuple dict 重点总结

    一.数字int(..)二.字符串replace/find/join/strip/startswith/split/upper/lower/formattempalte = "i am {na ...

  5. C/C++变量命名规则,个人习惯总结【转载】

    C_C++变量命名规则 原文地址:http://blog.sina.com.cn/s/blog_8a7012cf01017h9p.html 变量命名规则是为了增强代码的可读性和容易维护性.以下为C++ ...

  6. Azure VMSS ---- PowerShell创建标准镜像的VMSS集群

    VMSS的创建可以采用Portal.Powershell.Azure CLI或者Template. 但目前Portal创建有很多限制,本文将介绍如何用PowerShell来创建VMSS的集群. 具体的 ...

  7. Erlang pool management -- RabbitMQ worker_pool

    在RabbitMQ中,pool 是以worker_pool 的形式存在的, 其主要用途之一是对Mnesia transaction 的操作. 而在RabbitMQ 中, pool 中的worker 数 ...

  8. Sass、Less和Stylus

    1.背景介绍 1.Sass背景介绍 Sass是对CSS(层叠样式表)的语法的一种扩充,诞生于2007年,最早也是最成熟的一款CSS预处理器语言,它可以使用变量.常量.嵌套.混 入.函数等功能,可以更有 ...

  9. 2011-03-17免Oracle客户端连远程Oracle的方法

    1.http://www.oracle.com/technetwork/topics/winsoft-085727.html上下载对应版本的instanctclinet zip包 34M 解压后92M ...

  10. oracle——基础知识(二)未完

    1.select 查询 单独的一条 select 语句 可以一次查询多条记录:但是在 pl/sql 块中,select语句只能 使用INTO子句:必须并且只能返回一行 2.EXECUTE IMMEDI ...