本地php网站搭建,百度网站怎么建设的,免费注册网页的网站,秦皇岛短视频优化进程等待 wait和wait函数【Linux】 进程等待的概念进程等待的必要性进程等待的方法wait函数waitpid函数 非阻塞等待和阻塞等待的对比阻塞等待#xff1a;非阻塞等待 进程等待的概念 进程等待就是通过 wait/waitpid的方式#xff0c;让父进程对子进程进行等待子进程退出并且将… 进程等待 wait和wait函数【Linux】 进程等待的概念进程等待的必要性进程等待的方法wait函数waitpid函数 非阻塞等待和阻塞等待的对比阻塞等待非阻塞等待 进程等待的概念 进程等待就是通过 wait/waitpid的方式让父进程对子进程进行等待子进程退出并且将子进程进行资源回收的过程。
进程等待的必要性 为什么要进行进程等待 1. 因为父子进程的执行顺序是不确定的可能父进程会比子进程先一步退出此时就会让子进程成为僵尸进程子进程已经退出但是依旧占用着内存空间造成内存泄漏。 2. 由于一般来说子进程的出现是为了协助父进程完成一些任务子进程就像是父进程的手下小兵一样因此子进程完成父进程交给的任务退出后也一定要给父进程一个答复子进程是否完成是否出现异常等。 返回值 成功返回被等待进程pid失败返回-1。 参数 输出型参数获取子进程退出状态,不关心则可以设置成为NULL 3. 父进程通过进程等待的方式回收退出的子进程的资源获取子进程的退出信息也就是2。
进程等待的方法
wait函数
#include sys/types.h #inlclude sys/wait.h pid_t wait(int* status);
返回值 成功返回被等待进程pid失败返回-1。 参数 输出型参数获取子进程退出状态,不关心则可以设置成为NULL之后和waitpid一起介绍。 如何进行等待
调用wait函数进程等待子进程的退出。当子进程退出后会变成一个僵尸进程短暂的存在不会造成什么影响然后通过wait函数进程状态从僵尸状态Z变成死亡状态X。如果子进程没有退出父进程必须阻塞等待直到子进程变成Zwait自动回收返回。
#include iostream
#include unistd.h
#include sys/wait.h
#include cstdlib
int main()
{pid_t fd fork();if (fd 0){sleep(5);std::cout child: getpid() std::endl;exit(0);}if (fd 0){sleep(1);std::cout parent: getpid() std::endl;}sleep(50);return 0;
}子进程退出后由于父进程没有等待回收子进程变成僵尸进程 调用wait后子进程就会回收释放了
#include iostream
#include unistd.h
#include sys/wait.h
#include cstdlib
int main()
{pid_t fd fork();if (fd 0){sleep(5);std::cout child: getpid() std::endl;exit(0);}if (fd 0){sleep(1);std::cout parent: getpid() std::endl;wait(NULL);}sleep(50);return 0;
}waitpid函数
#include sys/types.h #inlclude sys/wait.h pid_ t waitpid(pid_t pid, int *status, int options); 返回值 当正常返回的时候waitpid返回收集到的子进程的进程ID 如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0 如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在 参数 pid Pid-1,等待任一个子进程。与wait等效。 Pid0.等待其进程ID与pid相等的子进程。 status: WIFEXITED(status): 若为正常终止子进程返回的状态则为真。查看进程是否是正常退出 WEXITSTATUS(status): 若WIFEXITED非零提取子进程退出码。查看进程的退出码 options: WNOHANG: 若pid指定的子进程没有结束则waitpid()函数返回0不予以等待。若正常结束则返回该子进 程的ID。 status其实就是个int型的输出型参数一共32bit但是我们只需要关注低位的16bit就行。下图是16bit status的示意图 使用方法
判断是否正常终止可以提取低7位如果全0就是正常终止 (status 0x7F)提取退出状态( (status 8) 0xFF)提取终止状态(status 0x7F)提取core dump ( (status 7) 0x1)
除了使用上面的方法也可以
判断是否正常终止WIFEXITED(status);若为正常终止子进程返回的状态则为真.提取子进程退出码WEXITSTATUS(status); 若WIFEXITED非零提取子进程退出码。查看进程的退出码
#include iostream
#include unistd.h
#include sys/wait.h
#include cstdlib
int main()
{pid_t fd fork();if (fd 0){sleep(5);std::cout child: getpid() std::endl;exit(8);}if (fd 0){int st;int ret waitpid(fd, st, 0);if (ret 0 (st 0x7F) 0){std::cout 退出状态 ((st 8) 0xFF) std::endl;}else if (ret 0){std::cout 终止信号 (st 0x7F) std::endl;}std::cout parent: getpid() std::endl;}return 0;
}正常终止 被kill杀死上面的代码中子进程存在的时间延长
#include iostream
#include unistd.h
#include sys/wait.h
#include cstdlib
int main()
{pid_t fd fork();if (fd 0){sleep(50);std::cout child: getpid() std::endl;exit(8);}if (fd 0){int st;int ret waitpid(fd, st, 0);if (ret 0 (st 0x7F) 0){std::cout 退出状态 ((st 8) 0xFF) std::endl;}else if (ret 0){std::cout 终止信号 (st 0x7F) std::endl;}std::cout parent: getpid() std::endl;}return 0;
}验证时通过while :; do ps axj | head -1 ps axj | grep test11 | grep -v grep; sleep 1; echo ###############; done的指令来过去子进程的pid。
非阻塞等待和阻塞等待的对比
阻塞等待
#include iostream
#include unistd.h
#include sys/wait.h 这里是引用#include cstdlib
int main()
{pid_t fd fork();if (fd 0){sleep(10);std::cout child: getpid() std::endl;exit(8);}if (fd 0){int ret;int st;do{ret waitpid(fd, st, 0);std::cout 如果是非阻塞等待则指向这个打印 std::endl;} while (ret 0);if (ret 0 (st 0x7F) 0){std::cout 退出状态 ((st 8) 0xFF) std::endl;}else if (ret 0){std::cout 终止信号 (st 0x7F) std::endl;}}return 0;
}可以看到由于waitpid函数是这样的waitpid(fd, st, 0);option也就是第三个参数为0表示阻塞等待所以如果是非阻塞等待则指向这个打印这句话只执行了一次。
非阻塞等待 非阻塞等待也叫非阻塞轮询式等待既然是轮询就需要使用while循环的进行waitpid否则如果waitpid没有等到子进程就会执行下面的指令直接执行完然后退出父进程。就不能回收子进程资源了。使用while时需要注意这句话如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0
#include iostream
#include unistd.h
#include sys/wait.h
#include cstdlib
int main()
{pid_t fd fork();if (fd 0){sleep(10);std::cout child: getpid() std::endl;exit(8);}if (fd 0){int ret;int st;do{ret waitpid(fd, st, WNOHANG);std::cout 如果是非阻塞等待则指向这个打印 std::endl;} while (ret 0);if (ret 0 (st 0x7F) 0){std::cout 退出状态 ((st 8) 0xFF) std::endl;}else if (ret 0){std::cout 终止信号 (st 0x7F) std::endl;}}return 0;
}可以看到由于waitpid函数是这样的waitpid(fd, st, WNOHANG);option也就是第三个参数为WNOHANG表示非阻塞等待所以如果是非阻塞等待则指向这个打印这句话只执行了数次。 创作不易你的点赞和关注都是对我莫大的鼓励再次感谢您的观看