首页 > 系统相关 >Linux多进程07-wait和waitpid

Linux多进程07-wait和waitpid

时间:2023-05-17 18:46:21浏览次数:49  
标签:07 int pid 进程 include waitpid wait

进程回收

  • 在每个进程退出的时候,内核释放该进程所有的资源、包括打开的文件、占用的内存等。但是仍然为其保留一定的信息,这些信息主要主要指进程控制块PCB的信息(包括进程号、退出状态、运行时间等)。

  • 父进程可以通过调用wait或waitpid得到它的退出状态同时彻底清除掉这个进程。

  • wait() 和 waitpid() 函数的功能一样,区别在于,wait() 函数会阻塞,waitpid() 可以设置不阻塞,waitpid() 还可以指定等待哪个子进程结束。

  • 一次wait或waitpid调用只能清理一个子进程,清理多个子进程应使用循环。

wait

#include <sys/types.h>
#include <sys/wait.h>

pid_t wait(int *wstatus);
    功能: 等待任意一个子进程结束,如果任意一个子进程结束了,次函数会回收子进程的资源

    参数:
        wstatus :进程退出的状态信息, 传入的是一个int类型的地址,传出参数
    返回:
        - 成功: 返回被回收的子进程的ID
        - 失败: 返回-1 (所有的子进程都结束)

    调用wait函数的进程会被挂起(阻塞),
    直到它的一个子进程退出或者收到一个不能被忽略的信号时才被唤醒,相当于继续往下执行
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int main(int argc, char const *argv[])
{
    //有个父进程,创建5个子进程
    pid_t pid;
    for (int i = 0; i < 5; i++)
    {
        pid = fork();
        if (pid == 0)
            break; //防止子进程产生孙子进程
    }

    if (pid > 0)
    {
        //父进程
        while (1)
        {
            printf("parent process, pid = %d\n", getpid());

            int ret = wait(NULL); //阻塞等待
            if(ret == -1){
                break;
            }
            printf("child process die, pid = %d\n", ret);

            sleep(1);
        }
    }
    else if (pid == 0)
    {
        //子进程
        while (1)
        {
            printf("child process, pid = %d\n", getpid());
            sleep(1);
        }
    }
    return 0;
}

waitpid

#include <sys/types.h>
#include <sys/wait.h>

pid_t waitpid(pid_t pid, int *wstatus, int options);
功能: 回收指定进程号的子进程, 可以设置是否阻塞
参数:
    pid:
        pid>0 : 某个子进程的pid
        pid=0 : 回收当前进程组的所有子进程
        pid=-1 : 回收所有子进程,相当于wait() (常用)
        pid<-1 : 某个进程组组id的绝对值,回收指定进程组中的子进程
    wstatus : 进程退出的状态信息, 传入的是一个int类型的地址,传出参数
    options : 设置阻塞或非阻塞
        0 阻塞
        WNOHANG 非阻塞
    返回:
        >0 子进程ID
        -0 options = WNOHANG ,表示还有子进程活着
        =-1 错误,或者没有子进程了
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char const *argv[])
{
    pid_t pid;
    for (int i = 0; i < 5; i++)
    {
        pid = fork();
        if (pid == 0)
            break;
    }

    if (pid > 0)
    {
        while (1)
        {
            printf("parent, pid = %d\n", getpid());
            sleep(1);

            int st;
            // int ret = waitpid(-1,&st,0); //阻塞
            int ret = waitpid(-1, &st, WNOHANG); //非阻塞

            if (ret == -1)
                break;

            if (ret == 0)
            {
                //说明还有子进程存在
                continue;
            }
            else if (ret > 0)
            {
                if (WIFEXITED(st))
                {
                    printf("退出的状态码: %d\n", WEXITSTATUS(st));
                }
                if (WIFSIGNALED(st))
                {
                    printf("被哪个信号干掉了: %d\n", WTERMSIG(st));
                }

                printf("child process die, pid = %d\n", ret);
            }
                }
    }
    else if (pid == 0)
    {
        while (1)
        {
            printf("child, pid = %d\n", getpid());
            sleep(1);
        }
        exit(0);
    }

    return 0;
}

退出信息相关宏函数

  • WIFEXITED(status) 非0,进程正常退出
  • WEXITSTATUS(status) 如果上宏为真,获取进程退出的状态(exit的参数)
  • WIFSIGNALED(status) 非0,进程异常终止
  • WTERMSIG(status) 如果上宏为真,获取使进程终止的信号编号
  • WIFSTOPPED(status) 非0,进程处于暂停状态
  • WSTOPSIG(status) 如果上宏为真,获取使进程暂停的信号的编号
  • WIFCONTINUED(status) 非0,进程暂停后已经继续运行

标签:07,int,pid,进程,include,waitpid,wait
From: https://www.cnblogs.com/anqwjoe/p/17409728.html

相关文章

  • STM32F107单片机驱动Dp83848以太网芯片程序 项目开发用到了Dp83848
    STM32F107单片机驱动Dp83848以太网芯片程序项目开发用到了Dp83848这一个以太网芯片,本人发现其配置起来比较麻烦,所以整理了一份STM32F107单片机驱动Dp83848的程序代码例程,方便大家学习相关代码的配置ID:3821630931468138......
  • excel-07-Excel函数由浅入深-Excel公式
    Excel公式定义:用加减乘除等运算符号,把一些数值、文本、函数等组合在一起,得出一个结果的数学算式。输入方法:手工输入与单元格引入手工输入:在的那远哥输入等号“=”,再输入公式,其中在编辑栏会出现公式具体表达,单元格会显示公式的表达结果。单元格引入:手动输入字符串,但是指定......
  • 【BZOJ2007】【NOI2010】海拔(对偶图,最短路)
    DescriptionYT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域。简单起见,可以将YT市看作一个正方形,每一个区域也可看作一个正方形。从而,YT城市中包括(n+1)×(n+1)个交叉路口和2n×(n+1)条双向道路(简称道路),每条双向道路连接主干道上两个相邻的交叉路口。下图为......
  • 《JavaScript权威指南第七版》13.3.4实现细节,关于“ES2017解释器可以把函数体分割成一
    读到“ES2017解释器可以把函数体分割成一系列独立的子函数,每个子函数都被传给位于他前面以await标记的那个期约的then方法”这一部分是比较困惑,也没有代码示例,很抽象,不易理解。自己写了个例子来复述一下这段话:functiongetPosts(){returnnewPromise(function(resolve,......
  • GYM100722C - Ticket to Ride
    首先考虑\(dp_{i,msk}\)表示当前连通了\(msk\)中所有关键点,并且当前连通的非关键点包含\(i\)的最小代价。然后考虑如何转移。我们先用\(Floyd\)预处理所有点对之间的最短路\(dist_{i,j}\)。同时,每次选取的两个用于合并的关键点集合一定没有交集,所以我们可以直接枚举子集......
  • 【Mysql】update时报错:Lock wait timeout exceeded; try restarting transaction
    1、查找正在执行的事务SELECT*FROMinformation_schema.INNODB_TRX;2、杀掉LOCKWAIT的进程trx_mysql_thread_id:进程idkillxxxOR3、查看所有进程SHOWPROCESSLIST;4、杀掉异常的进程,比如Sleep状态、影响你正在操作的业务的进程id:进程idkillxxx......
  • 基于STM32F407/STM32H743芯片和SOEM的E therCAT主站源码 提供配套CUBE工程和。
    基于STM32F407/STM32H743芯片和SOEM的EtherCAT主站源码提供配套CUBE工程和。可配套正点原子探索者开发板使用,或任何带以太网口的407/H743板子。支持DC同步。可配合汇川IS620N、埃斯顿ProNet、迈信EP3E、台达A2-E、伟创SD700、松下A5B/A6B和欧姆龙G5系列驱动器使用,或提供想适配的......
  • C#异步方法async/await的三种返回类型
    有群友问C#异步方法async返回值Task和void的区别?看似简单,但不容易把它们用好。在C#中的异步编程已经成为现代编程的标配,异步方法(async/await)是实现异步编程的一种常用方式。在异步方法中,可以使用Task或void作为返回类型,还可以使用ValueTask返回类型。本文将介绍异步方法中3个......
  • 07-为什么要做接口自动化测试
    目前系统研发多为前后端分离,当后端接口研发完成后,可以不依赖前端界面通过接口测试提前发现问题并解决。同时由于软件迭代周期不断缩短,开发新功能后又担心影响原有功能,可以通过接口自动化进行原有功能快速回归测试,将更多精力专注于迭代功能测试,这样才能放心地发布产品。由此看来,接......
  • C++黑马程序员——P207-209. deque容器 插入和删除,数据存取,排序操作
    P207.deque容器——插入和删除P208.deque容器——数据存取P209.deque容器——排序操作P207.deque插入和删除 ————————————————————————————————————————————————————————1#include<iostream>2#......