肥西县城乡建设局网站,古建设计素材网站,电商网站建设网,网站模板中心 网站推荐进程等待必要性之前讲过#xff0c;子进程退出#xff0c;父进程如果不管不顾#xff0c;就可能造成‘僵尸进程’的问题#xff0c;进而造成内存泄漏。另外#xff0c;进程一旦变成僵尸状态#xff0c;那就刀枪不入#xff0c;“杀人不眨眼”的kill -9 也无能为力#…进程等待必要性之前讲过子进程退出父进程如果不管不顾就可能造成‘僵尸进程’的问题进而造成内存泄漏。另外进程一旦变成僵尸状态那就刀枪不入“杀人不眨眼”的kill -9 也无能为力因为谁也没有办法杀死一个已经死去的进程。最后父进程派给子进程的任务完成的如何我们需要知道。如子进程运行完成结果对还是不对或者是否正常退出。父进程通过进程等待的方式回收子进程资源获取子进程退出信息进程等待的方法通过man手册进程查看man 2 waitwait()函数#includesys/types.h
#includesys/wait.h
pid_t wait(int*status);
返回值成功返回被等待进程pid失败返回-1。
参数输出型参数获取子进程退出状态,不关心则可以设置成为NULL下面测试一下wait()函数接下来观察下进程状态首先运行 while :; do ps axj | head -1 ps ajx | grep mytest | grep -v grep; sleep 1; echo ----------------; done接下来执行程序执行程序的同时查看进程状态这样观察不到现象代码改进一下waitpid()函数pid_ t waitpid(pid_t pid, int *status, int options);
返回值当正常返回的时候waitpid返回收集到的子进程的进程ID如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在
参数pidPid-1,等待任一个子进程。与wait等效。Pid0.等待其进程ID与pid相等的子进程。status:WIFEXITED(status): 若为正常终止子进程返回的状态则为真。查看进程是否是正常退出WEXITSTATUS(status): 若WIFEXITED非零提取子进程退出码。查看进程的退出码options:WNOHANG: 若pid指定的子进程没有结束则waitpid()函数返回0不予以等待。若正常结束则返回该子进程的ID。1.如果子进程已经退出调用wait/waitpid时wait/waitpid会立即返回并且释放资源获得子进程退出信息。2.如果在任意时刻调用wait/waitpid子进程存在且正常运行则进程可能阻塞。3.如果不存在该子进程则立即出错返回。获取子进程status wait和waitpid都有一个status参数该参数是一个输出型参数由操作系统填充。如果传递NULL表示不关心子进程的退出状态信息。否则操作系统会根据该参数将子进程的退出信息反馈给父进程。status不能简单的当作整形来看待可以当作位图来看待具体细节如下图只研究status低16比特位下面是获取退出码#include unistd.h
#include stdio.h
#include stdlib.h
#include sys/types.h
#include sys/wait.h
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(107);}// 父进程int status 0;pid_t ret_id waitpid(id, status, 0);printf(我是父进程等待子进程成功,pid:%d,ppid:%d,ret_id:%d,child exit code:%d\n, getpid(), getppid(), ret_id, (status 8) 0xFF);return 0;
}
其中status80xff获得整型值下面是获取异常信号码获取异常信号status0x7f得出整型值退出码为0我们制造一个异常在查看异常信号我们继续改下程序使程序无限循环死循环也可以杀掉进程。父进程在等待子进程的时候也可以做别的事情具体代码实现进程的阻塞等待方式#include unistd.h
#include stdio.h
#include stdlib.h
#include sys/types.h
#include sys/wait.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;
}进程的非阻塞等待方式#include unistd.h
#include stdio.h
#include stdlib.h
#include sys/types.h
#include sys/wait.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(1);}else{int status 0;pid_t ret 0;do{ret waitpid(-1, status, WNOHANG); // 非阻塞式等待if (ret 0){printf(child is running\n);}sleep(1);} while (ret 0);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;
}