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){ //son printf("I'm process child, pid = %d\n", getpid()); sleep(5); exit(4); } else { //parent do { 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){ //son printf("I'm process child, pid = %d\n", getpid()); sleep(5); exit(4); } else { //parent do { 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,並且子進程尚未結束。