网站建设 需求,ip访问 wordpress,保定seo推广公司,秦皇岛哪家做网站好序言#xff1a; 之前讲过#xff0c;子进程退出#xff0c;父进程如果不管不顾#xff0c;就可能造成‘僵尸进程’的问题#xff0c;进而造成内存泄漏。因此#xff0c;为了解决这个问题#xff0c;就需要用到有关 “进程等待” 的基本知识#xff01;#xff01; 之前讲过子进程退出父进程如果不管不顾就可能造成‘僵尸进程’的问题进而造成内存泄漏。因此为了解决这个问题就需要用到有关 “进程等待” 的基本知识 目录
一进程的等待必要性
二进程等待的方法
1、wait方法
2、waitpid方法
三获取子进程status 1、进程的阻塞等待方式
2、进程的非阻塞等待方式
总结 一进程的等待必要性
进程等待通常是指父进程等待子进程的执行完成。当一个进程创建了一个子进程并希望在子进程执行完成后再继续执行自己的任务时父进程需要等待子进程的完成。
以下是一些常见的原因和情况需要进程等待 避免僵尸进程如果父进程不等待子进程完成而直接退出子进程可能会成为僵尸进程。僵尸进程是已经完成执行但尚未被父进程回收的子进程。为了避免僵尸进程的产生父进程需要等待子进程完成并回收子进程的资源 父子进程间通信在使用fork()系统调用创建子进程时父进程通常需要等待子进程完成以确保获取子进程的执行结果或处理子进程的退出状态 最后父进程派给子进程的任务完成的如何我们需要知道。如子进程运行完成结果对还是不对或者是否正常退出。 因此我们可以得出进程等待就是
通过系统调用获取子进程退出码或者退出信号的方式顺便释放内存问题 二进程等待的方法
进程等待可以通过操作系统提供的函数来实现主要有以下两种方法来进程等待操作
waitpid函数等待指定的子进程完成。可以设置选项参数来指定等待条件。wait函数等待任意一个子进程完成并获取其退出状态。 1、wait方法
遇到新的函数如果不认识就先去系统中查询一下 【说明】
返回值成功返回被等待进程pid失败返回-1。参数输出型参数获取子进程退出状态,不关心则可以设置成为NULL
接下来通过代码简单的 int main(){pid_t id fork();if(id 0){//子进程int cnt 5;while(cnt){printf(我是子进程我还活着呢我还有%dS, pid: %d, ppid%d\n, cnt --, getpid(), getppid());sleep(1);}exit(0);}sleep(10);// 父进程pid_t ret_id wait(NULL);printf(我是父进程等待子进程成功, pid: %d, ppid: %d, ret_id: %d\n,getp id(), getppid(), ret_id); sleep(5);}输出显示 【解释】
上述代码是一个简单的示例展示了父进程创建子进程并使用wait函数等待子进程完成。 进阶着又有一个问题那就是父进程在 wait的时候如果子进程没有退出那么父进程在干什么呢? 我们把代码改一下看输出结果。代码如下 int main(){pid_t id fork();if(id 0){//子进程int cnt 5;while(cnt){printf(我是子进程我还活着呢我还有%dS, pid: %d, ppid%d\n, cnt --, getpid(), getppid());sleep(1);}exit(0);}// 父进程pid_t ret_id wait(NULL);printf(我是父进程等待子进程成功, pid: %d, ppid: %d, ret_id: %d\n,getp id(), getppid(), ret_id); sleep(5);}输出显示 2、waitpid方法
wait 和 waitpid 的头文件一样。具体如下 pid_ t waitpid(pid_t pid, int *status, int options); 返回值 1、当正常返回的时候waitpid返回收集到的子进程的进程ID 2、如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0 3、 如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在参数 pid 1. Pid-1,等待任一个子进程。与wait等效。 2. Pid0.等待其进程ID与pid相等的子进程。 status: 1.WIFEXITED(status): 若为正常终止子进程返回的状态则为真。查看进程是否是正常退出 2.WEXITSTATUS(status): 若WIFEXITED非零提取子进程退出码。查看进程的退出码 options: 1.WNOHANG: 若pid指定的子进程没有结束则waitpid()函数返回0不予以等待。若正常结束则返回该子进程的ID。 如果子进程已经退出调用wait/waitpid时wait/waitpid会立即返回并且释放资源获得子进程退出信息。如果在任意时刻调用wait/waitpid子进程存在且正常运行则进程可能阻塞。如果不存在该子进程则立即出错返回。 三获取子进程status wait和waitpid都有一个status参数该参数是一个输出型参数由操作系统填充。如果传递NULL表示不关心子进程的退出状态信息。否则操作系统会根据该参数将子进程的退出信息反馈给父进程。status不能简单的当作整形来看待可以当作位图来看待具体细节如下图只研究status低16比特位 具体可以向下述这样理解 判断一个进程是否正常退出只需要判断是否接收到进程终止信号。大于0异常退出有进程终止信号等于0正常退出。 代码演示
int main()
{pid_t id fork();if(id 0){//子进程int cnt 5;while(cnt){printf(我是子进程我还活着呢我还有%dS, pid: %d, ppid: %d\n, cnt--, getpid(), getppid());sleep(1);}exit(111);} // 父进程int status 0 ;pid_t ret_id waitpid(id, status, 0);printf(我是父进程等待子进程成功, pid: %d, ppid: %d, ret_id: %d,child exit code: %d, child exit signal: %d\n\,getpid(), getppid(), ret_id,(status8)0xFF, status 0x7F);sleep(2);
}输出结果 1、进程的阻塞等待方式
#include stdio.h
#include stdlib.h
#include sys/types.h
#include sys/wait.h
#include unistd.hint main()
{pid_t pid;pid fork();if(pid 0){printf(%s fork error\n,__FUNCTION__);return 1;} else if( pid 0 ){ //childprintf(child is run, pid is : %d\n,getpid());sleep(5);exit(257);} else{int status 0;pid_t ret waitpid(-1, status, 0);//阻塞式等待等待5Sprintf(this is test for wait\n);if( WIFEXITED(status) ret pid ){printf(wait child 5s success, child return code is :%d.\n,WEXITSTATUS(status));}else{printf(wait child failed, return.\n);return 1;}}return 0;
}
输出展示 此运行结果是子进程正常退出的场景 2、进程的非阻塞等待方式 1 #includestdio.h2 #includeunistd.h3 #includestdlib.h4 #include sys/types.h5 #include sys/wait.h6 7 int main()8 {9 pid_t pid;10 pid fork();11 if(pid 0){12 printf(%s fork error\n,__FUNCTION__);13 return 1;14 }else if( pid 0 ){ //child15 printf(child is run, pid is : %d\n,getpid());16 sleep(5);17 exit(1);18 } else{19 int status 0;20 pid_t ret 0;21 do22 {23 ret waitpid(-1, status, WNOHANG);//非阻塞式等待24 if( ret 0 ){25 printf(child is running\n);26 }27 sleep(1);28 }while(ret 0);29 if( WIFEXITED(status) ret pid ){30 printf(wait child 5s success, child return code is :%d.\n,WEXITS TATUS(status));31 }else{32 printf(wait child failed, return.\n);33 return 1;34 }35 } 36 return 0;37 }38 输出展示 调用 waitpid 函数非阻塞WNOHANG父子进程交替打印进行各自的循环大概 5s 之后子进程 可以看到子进程由 S 变成 Z。 若WIFEXITED(status)为真----进程正常退出 若WEXITSTATUS(status)0----WEXITSTATUS(status)表示子进程的退出码 总结 以上便是关于进程等待的全部知识了。感谢大家的观看与支持