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,并且子進程尚未結束。