保定网站建设解决方案,做个网址多少钱,wordpress 经典教程,软考证书含金量排名进程一旦调用了wait#xff0c;就立即阻塞自己#xff0c;由wait自动分析是否当前进程的某个子进程已经退出#xff0c;如果让它找到了这样一个已经变成僵尸的子进程#xff0c;wait就会收集这个子进程的信息#xff0c;并把它彻底销毁后返回#xff1b;如果没有找到这样…进程一旦调用了wait就立即阻塞自己由wait自动分析是否当前进程的某个子进程已经退出如果让它找到了这样一个已经变成僵尸的子进程wait就会收集这个子进程的信息并把它彻底销毁后返回如果没有找到这样一个子进程wait就会一直阻塞在这里直到有一个出现为止。
#include sys/types.h
#include sys/wait.hpid_t wait(int *status)
参数status用来保存被收集进程退出时的一些状态它是一个指向int类型的指针。但如果我们对这个子进程是如何死掉的毫不在意只想把这个僵尸进程消灭掉事实上绝大多数情况下我们都会这样想我们就可以设定这个参数为NULL 如果成功wait会返回被收集的子进程的进程ID如果调用进程没有子进程调用就会失败此时wait返回-1同时errno被置为ECHILD。 下面是范例
int main()
{pid_t pid fork();switch (pid){case -1:perror (fork);break;case 0: // 子进程printf (我是子进程我的ID是%d\n, getpid());sleep (3);exit (0);default: // 父进程printf (等待子进程挂掉\n);sleep (3);pid_t childId wait (NULL);printf (成功处理一个子进程该子进程是%d\n, childId);sleep (3);break;}return 0;
}运行后发现3秒钟的等待时间这就是我们设定的让子进程睡眠的时间只有子进程从睡眠中苏醒过来它才能正常退出也就才能被父进程捕捉到。其实这里我们不管设定子进程睡眠的时间有多长父进程都会一直等待下去。
数status如果参数status的值不是NULLwait就会把子进程退出时的状态取出并存入其中这是一个整数值int指出了子进程是正常退出还是被非正常结束的一个进程也可以被其他进程用信号结束我们将在以后的文章中介绍以及正常结束时的返回值或被哪一个信号结束的等信息。由于这些信息被存放在一个整数的不同二进制位中所以用常规的方法读取会非常麻烦人们就设计了一套专门的宏macro来完成这项工作下面我们来学习一下其中最常用的两个
1WIFEXITED(status)这个宏用来指出子进程是否为正常退出的如果是它会返回一个非零值。
请注意虽然名字一样这里的参数status并不同于wait唯一的参数–指向整数的指针status而是那个指针所指向的整数切记不要搞混了。
2 WEXITSTATUS(status)当WIFEXITED返回非零值时我们可以用这个宏来提取子进程的返回值如果子进程调用exit(5)退出WEXITSTATUS(status)就会返回5如果子进程调用exit(7)WEXITSTATUS(status)就会返回7。请注意如果进程不是正常退出的也就是说WIFEXITED返回0这个值就毫无意义。 实例
// status保存了被收集进程退出时的一些状态
int main()
{pid_t pid fork();switch (pid){case -1:perror (fork);break;case 0: // 子进程printf (我是子进程我的ID是%d\n,getpid());while (1);exit (0);default: // 父进程printf (等待子进程挂掉\n);int status;pid_t childId wait (status);printf (成功处理一个子进程该子进程是%d %d\n, childId, status);if (WIFEXITED(status)){printf (正常死亡\n);}else{printf (被人做掉\n);}break;}return 0;
}
利用kill 杀死子进程。 wait一次只能处理一个僵尸进程
// wait一次只能处理一个僵尸进程
int main()
{int count 10;while (count--){pid_t pid fork();switch (pid){case -1:perror (fork);break;case 0: // 子进程printf (我是子进程我的ID是%d\n, getpid());sleep (3);exit (0);default: // 父进程break;}}printf (等待子进程挂掉\n);while (1){pid_t childId wait(NULL);if (-1 childId){break;}printf (成功处理一个子进程该子进程是%d\n, childId);}return 0;
} #include sys/types.h
#include sys/wait.hpid_t waitpid(pid_t pid,int *status,int options)
从本质上讲系统调用waitpid和wait的作用是完全相同的但waitpid多出了两个可由用户控制的参数pid和options从而为我们编程提供了另一种更灵活的方式。下面我们就来详细介绍一下这两个参数
pid 从参数的名字pid和类型pid_t中就可以看出这里需要的是一个进程ID。但当pid取不同的值时在这里有不同的意义。
pid0时只等待进程ID等于pid的子进程不管其它已经有多少子进程运行结束退出了只要指定的子进程还没有结束waitpid就会一直等下去。 pid-1时等待任何一个子进程退出没有任何限制此时waitpid和wait的作用一模一样。 pid0时等待同一个进程组中的任何子进程如果子进程已经加入了别的进程组waitpid不会对它做任何理睬。 pid-1时等待一个指定进程组中的任何子进程这个进程组的ID等于pid的绝对值。
options options提供了一些额外的选项来控制waitpid目前在Linux中只支持WNOHANG和WUNTRACED两个选项这是两个常数可以用”|”运算符把它们连接起来使用 WNOHANG 如果没有任何已经结束的子进程则马上返回不予以等待。 WUNTRACED 如果子进程进入暂停执行情况则马上返回但结束状态不予以理会。
返回值如果执行成功则返回子进程识别码(PID)如果有错误发生则返回-1。失败原因存于errno中。
int main()
{pid_t pid fork();switch (pid){case -1:perror (fork);break;case 0: // 子进程printf (我是子进程我的ID是%d\n, getpid());while (1);exit (0);default: // 父进程printf (等待子进程挂掉\n);int status;pid_t childId waitpid (-1, NULL, WNOHANG);printf (成功处理一个子进程该子进程是%d, %d\n, childId, status);break;}return 0;
}