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.pswp.cn/news/384896.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/384896.shtml
英文地址,請注明出處:http://en.pswp.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…