进程等待:
进程等待:父进程对子进程进行进程等待,等待是为了读取子进程的运行结果
进程等待的方法:
- wait方法 (阻塞等待)
- 头文件:#include<sys/types.h> #include<sys/wait.h>
- pid_t wait(int*status)
- 返回值:成功返回被等待进程pid,失败返回-1。
- 参数:输出型参数,获取子进程退出状态,不关心则可以设置成为NULL
- wait函数输一个阻塞式函数,一直等到子程序结束才返回。
注:status是状态码,这个字节的最后一个字节判断是否正常终止。最后一个字节是0——正常终止;最后一个字节是非0——异常终止。异常终止的时候返回终止信号的序号。(int status =0; wait(&status),一般wait这么写)
wai的注意事项:
- wait调用的次数必须和子进程的个数一致。(和fork一致)
- wait调用次数比较少,就会导致僵尸进程;调用次数最多,会调用出错。
- 如果有多个子进程,任何一个子进程退出就会触发wait的返回。
- waitpid:等待指定的进程
pid_ t waitpid(pid_t pid, int *status, int options);
pid_t pid:子进程pid
int *status:状态码
int options:影响执行行为,位图
//位图的一些含义: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1000 0000 0001 //改变其中的某些位设为1,表示一种情况,几个1几种情况 //很多Linux系统调用中,使用类似参数作为辅助选项,影响函数的执行行为
注意:
Pid:
Pid=-1,等待任一个子进程。与wait等效。 waitpid(-1,NULL,0) 和 wait(NULL) 等价
Pid>0,等待其进程ID与pid相等的子进程。
options:
WNOHANG: 若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若正常结束,则返回该子进程的ID。
注:WNOHANG是个宏,代表整数1;还有其他选项2,4,8(2^n);1就是把位图的第一位制位1,以此类推)
返回值:
- 当正常返回的时候waitpid返回收集到的子进程的进程ID。
- 如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0。
- 如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在。
非阻塞轮询式的wait:
加上了 WNOHANG 就是非阻塞的等待。 即: waitpid(-1,NULL,WNOHANG)
好处:能够灵活控制代码,充分利用等待时间去做其他的事情
坏处:代码写起来更复杂
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>
int main()
{
pid_t ret1 = fork();
if (ret1 == 0)
{
printf("child1 %d\n", getpid());
sleep(3);
exit(0);
}
pid_t ret2 = fork();
if (ret2 == 0)
{
printf("child2 %d\n", getpid());
sleep(1);
exit(0);
}
printf("father %d\n", getpid());
//father
//父进程如果不关注具体的子进程推出状态 wait(NULL)
//阻塞式等待
int ret = waitpid(ret1,NULL,0);
printf("wait1 %d\n", ret);
int ret = waitpid(ret2, NULL, 0);
printf("wait2 %d\n", ret);
return 0;
}
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>
int main()
{
pid_t ret1 = fork();
if (ret1 == 0)
{
printf("child1 %d\n", getpid());
sleep(3);
exit(0);
}
pid_t ret2 = fork();
if (ret2 == 0)
{
printf("child2 %d\n", getpid());
sleep(1);
exit(0);
}
printf("father %d\n", getpid());
//father
//父进程如果不关注具体的子进程推出状态 wait(NULL)
//非阻塞式的等待
//加上了WNOHANG就是非阻塞的等待 //轮询式
int count;
while (1)
{
int ret = waitpid(-1, NULL, WNOHANG);
printf("wait1 %d\n", ret);
if (ret > 0)
break;
count++; //查看多少次 //往返,反复等待多少次。
}
while (1) {
sleep(1);
}
printf("count= %d\n",count);
}