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