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