waitpid()函数

waitpid函数

 作用同于wait,但可指定pid进程清理,可以不阻塞。

pid_t waitpid(pid_t pid,int *status,int options);成功:返回清理掉的子进程ID;失败:-1(无子进程)

特殊参数和返回情况:

参数pid:

       >0 回收指定ID的子进程

       -1 回收任意子进程(相当于wait)

       0 回收和当前调用waitpid一个组的所有子进程

       < -1 回收指定进程组内的任意子进程

返回0:参数3为WNOHANG,且子进程正在运行。

注意:一次wait或waitpid调用只能清理一个子进程,清理多个子进程需要用到循环

/***
loop_wait.c
***/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>int main(int argc, char *argv[])
{int n = 5, i;                //默认创建5个子进程
    pid_t p, q;if(argc == 2){    n = atoi(argv[1]);}for(i = 0; i < n; i++)     {//出口1,父进程专用出口p = fork();if(p == 0) {break;            //出口2,子进程出口,i不自增} else if (i == 3){q = p;}}if(n == i){sleep(n);printf("I am parent, pid = %d\n", getpid(), getgid());//pid_t pid = waitpid(q, NULL, WNOHANG);
//        pid_t pid = wait(NULL);//printf("child pid = %d\n", pid);while(1);} else {sleep(i);printf("I'm %dth child, pid = %d, gpid=%d\n", i+1, getpid(), getgid());while(1);}return 0;
}
/***
waitpid.c
***/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>int main(void)
{pid_t pid, pid2, wpid;int flg = 0;pid = fork();pid2 = fork();if(pid == -1){perror("fork error");exit(1);} else if(pid == 0){        //sonprintf("I'm process child, pid = %d\n", getpid());sleep(5);                exit(4);} else {                    //parentdo {wpid = waitpid(pid, NULL, WNOHANG);//wpid = wait(NULL);printf("---wpid = %d--------%d\n", wpid, flg++);if(wpid == 0){printf("NO child exited\n");sleep(1);        }} while (wpid == 0);        //子进程不可回收if(wpid == pid){        //回收了指定子进程printf("I'm parent, I catched child process,""pid = %d\n", wpid);} else {printf("other...\n");}}return 0;
}
/***
waitpid2.c
***/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>int main(void)
{pid_t pid, pid2, wpid;int flg = 0;pid = fork();pid2 = fork();if(pid == -1){perror("fork error");exit(1);} else if(pid == 0){        //sonprintf("I'm process child, pid = %d\n", getpid());sleep(5);                exit(4);} else {                    //parentdo {wpid = waitpid(pid, NULL, WNOHANG);//wpid = wait(NULL);printf("---wpid = %d--------%d\n", wpid, flg++);if(wpid == 0){printf("NO child exited\n");sleep(1);        }} while (wpid == 0);        //子进程不可回收if(wpid == pid){        //回收了指定子进程printf("I'm parent, I catched child process,""pid = %d\n", wpid);} else {printf("other...\n");}}return 0;
}
/***
waitpid3.c
***/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>int main(int argc, char *argv[])
{int n = 5, i;                
pid_t p, q;if(argc == 2){    n = atoi(argv[1]);}q = getpid();for(i = 0; i < n; i++)     {p = fork();if(p == 0) {break;            } }if(n == i){  // parent
        sleep(n);printf("I am parent, pid = %d\n", getpid());for (i = 0; i < n; i++) {p = waitpid(0, NULL, WNOHANG);printf("wait  pid = %d\n", p);}} else {sleep(i);printf("I'm %dth child, pid = %d\n", i+1, getpid());}return 0;
}

waitpid:

       参1:    pid  > 0       指定进程id回收

                     pid = -1        回收任意子进程

                     pid = 0          回收本组任意子进程

                     pid < -1        回收该进程组的任意子进程

       参2:    status:

                     返回:成功:pid  失败 -1

                     status:传出参数

                     1: 阻塞等待子进程

                     2: 回收子进程资源

                     3:    获取子进程结束状态:1)WIFEXITED()真

                                                                      WEXITSTATUS()获取子进程退出状态

                                                               2)WIFSIGNALED() 真

                                                                      WTERMSIG()获取导致子进程终止的信号的                                                                                           编码

参3:    0 :(wait)阻塞回收

              WBNIOHANG:非阻塞回收(轮询)

返回值:       成功:pid  失败 -1  返回 0 值: 参3传WNOHANG,并且子进程尚未结束。

转载于:https://www.cnblogs.com/wanghao-boke/p/11311806.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/384896.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

孤儿进程、僵尸进程

孤儿进程&#xff1a;父进程先于子进程结束&#xff0c;则子进程成为孤儿进程&#xff0c;子进程的父进程成为init进程&#xff0c;称为init进程领养孤儿进程。 /*** orphan.c ***/ #include <stdio.h> #include <unistd.h> #include <sys/wait.h>int main(v…

友元函数

类的友元函数是定义在类外部&#xff0c;但有权访问类的所有私有成员和保护成员。尽管友元函数的原型有在类的定义中出现过&#xff0c;但友元函数并不是成员函数。 友元可以是一个函数&#xff0c;该函数被称为友元函数&#xff1b;友元也可以是一个类&#xff0c;该类被称为友…

this指针

在C中&#xff0c;每一个对象都能够通过this指针来访问自己的地址。this指针是所有成员函数的隐含参数。因此&#xff0c;在成员函数内部&#xff0c;它可以用来指向调用对象。 友元函数是没有this指针的&#xff0c;因为友元不是类的成员&#xff0c;只有成员函数才有this指针…

静态成员

我们可以使用static关键字把类成员定义为静态的。当我们声明类的成员为静态时&#xff0c;这意味着无论创建多少个类的对象&#xff0c;静态成员都只有一个副本。 静态成员在类的所有对象都是贡献的。如果不存在其他的初始化语句&#xff0c;在创建第一个对象时&#xff0c;所有…

Linux进程通信之mmap

mmap()函数&#xff1a; void *mmap(void* addr,size_t length,int port,int flags,int fd,off_t offset); 返回&#xff1a;成功&#xff1a;返回创建的映射区首地址&#xff1b;失败&#xff1a;MAP_FAILED 宏 参数&#xff1a; addr: 建立映射区的首地址&#xff0c;由…

Linux之文件通信

/** 后执行,尝试读取另外一个进程写入文件的内容*/ #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> #include <string.h>int main(void) {char buf[1024];char *str "----------test2 write secesuss---…

重载函数和重载运算符

C允许在同一个作用域中的某个函数和运算符指定多个定义&#xff0c;分别称为函数重载和运算符重载。 重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明&#xff0c;但他们的参数列表和定义&#xff08;实现&#xff09;不相同。 当调用一个重载函数…

二元运算符重载

以非成员函数方式重载运算符 /*** overtwo.cpp ***/ #include<iostream> using namespace std;class Box {public:Box(double l 2.0,double b 2.0,double h 2.0){length l;breadth b;height h;}double getVolume(){return length*breadth*height;}private:double l…

一元运算符重载

一元运算符只对一个操作数进行操作&#xff0c;下面是一元运算符实例&#xff1a; 递增运算符&#xff08;&#xff09; 和递减运算符&#xff08;--&#xff09;一元减运算符&#xff0c;即符号&#xff08;-&#xff09;逻辑非运算符&#xff08;!&#xff09;/*** overone.c…

关系运算符重载

C语言支持各种关系运算符重载(<,>,>,<,)&#xff0c;他们可用于比较C内置的数据类型。 支持重载任意一个关系运算符&#xff0c;重载后的关系运算符可以用于比较类的对象。 /*** overrealate.cpp ***/ #include<iostream> using namespace std;class Distanc…

kill函数

kill函数/命令产生信号 kill命令产生信号&#xff1a;kill -SIGKILL pid kill函数&#xff1a;给指定进程发送指定信号(不一定杀死) int kill(pid_t pid, int sig); 成功&#xff1a;0&#xff1b;失败&#xff1a;-1 (ID非法&#xff0c;信号非法&#xff0c;普通用户杀i…

下标运算符重载

重载该运算符用于增强操作C数组的功能。 /*** subscript.cpp ***/ #include<iostream> using namespace std; const int SIZE 10;class safearay {private:int arr[SIZE];public:safearay(){register int i;for(i 0; i < SIZE ;i){arr[i] i;} }int& operator…

赋值运算符重载

重载赋值运算符&#xff08;&#xff09;&#xff0c;用于创建一个对象&#xff0c;比如拷贝构造函数。 /*** evaluate.cpp ***/ #include<iostream> using namespace std;class Distance {private:int feet;int inches;public:Distance(){feet 0;inches 0;}Distance(i…

运算符小括号重载

函数调用运算符()可以被重用于类的对象。当重载()时&#xff0c;没有创造一个新的调用函数的方式&#xff0c;相反地&#xff0c;这是创建一个可以传递任意数目参数的运算符函数。 /*** bracke.cpp ***/ #include<iostream> using namespace std;class Distance {private…

自增自减运算符重载

递增运算符&#xff08;&#xff09;和递减运算符&#xff08;--&#xff09;是C语言中两个重要的一元运算符。 /*** addMyself.cpp ***/ #include<iostream> using namespace std;class Time {private:int hours;int minutes;public:Time(){hours 0;minutes 0;}Time(i…

输入输出运算符重载

C能够使用流提取运算符>>和流插入运算符<< 来输入输出内置数据类型&#xff0c;也可以重载流提取运算符和流插入运算符来操作对象等用户自定义的数据类型。 我们有时需要把运算符重载函数声明为类的友元函数&#xff0c;这样我们就能不用构造对象而直接调用函数。 …

alarm函数

alarm函数 设置定时器(闹钟)。在指定seconds后&#xff0c;内核会给当前进程发送14&#xff09;SIGALRM信号。进程收到该信号&#xff0c;默认动作终止。 每个进程都有且只有唯一个定时器。 unsigned int alarm(unsigned int seconds); 返回0或剩余的秒数&#xff0c;无失败…

信号捕捉

signal函数 注册一个信号捕捉函数&#xff1a; typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler); 该函数由ANSI定义&#xff0c;由于历史原因在不同版本的Unix和不同版本的Linux中可能有不同的行为。因此应该尽量避免使用它&#x…

打印未决信号集

信号集操作函数 内核通过读取未决信号集来判断信号是否应被处理。信号屏蔽字mask可以影响未决信号集。而我们可以在应用程序中自定义set来改变mask。已达到屏蔽指定信号的目的。 信号集设定 sigset_t set; // typedef unsigned long sigset_t; int sigemptyset(sigset_…

sigaction()函数

sigaction函数 修改信号处理动作&#xff08;通常在Linux用其来注册一个信号的捕捉函数&#xff09; int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); 成功&#xff1a;0&#xff1b;失败&#xff1a;-1&#xff0c;设置errno 参数&a…