我有这个代码,需要父母分叉3个孩子。
您如何知道(和)将" wait()" 语句放在哪里以杀死
僵尸进程?
如果你有Linux,查看僵尸进程的命令是什么? 虚拟盒子?
main(){
pid_t child;
printf("-----------------------------------\n");
about("Parent");
printf("Now .. Forking !!\n");
child = fork();
int i=0;
for (i=0; i<3; i++){
if (child < 0) {
perror ("Unable to fork");
break;
}
else if (child == 0){
printf ("creating child #%d\n", (i+1));
about ("Child");
break;
}
else{
child = fork();
}
}
}
void about(char * msg){
pid_t me;
pid_t oldone;
me = getpid();
oldone = getppid();
printf("***[%s] PID = %d PPID = %d.\n", msg, me, oldone);
}
答案 0 :(得分:8)
你怎么知道(和)把#34; wait()&#34;放在哪里?要杀人的说法 僵尸进程?
如果您的父母只产生一小部分固定数量的孩子;不关心他们何时或是否停止,恢复或完成; 和本身会快速退出,然后您无需使用wait()
或waitpid()
来清理子进程。 init进程(pid 1)负责处理孤立的子进程,并在完成后对其进行清理。
但是,在任何其他情况下,您必须wait()
进行子进程。这样做可以释放资源,确保孩子已经完成,并允许您获得孩子的退出状态。通过waitpid()
,当孩子被信号停止或恢复时,如果您愿意,也可以通知您。
至于,其中执行等待,
wait()
。waitpid(-1, NULL, WNOHANG)
以收集一个僵尸孩子(如果有的话),如果有的话不是任何人。特别是,wait()
之后,您必须立即不 fork()
(无条件地),因为父级和子级运行相同的代码。必须使用fork()
的返回值来确定您是否在子项中(返回值== 0),还是在父项中(任何其他返回值)。此外,只有在分叉成功的情况下,父母才必须wait()
,在这种情况下,fork()
会返回孩子的pid,该pid始终大于零。返回值小于零表示无法分叉。
你的程序并不真正需要wait()
,因为它会产生四个(而不是三个)孩子,然后退出。但是,如果您希望父母在任何时间最多只有一个活孩子,那么您可以这样写:
int main() {
pid_t child;
int i;
printf("-----------------------------------\n");
about("Parent");
for (i = 0; i < 3; i++) {
printf("Now .. Forking !!\n");
child = fork();
if (child < 0) {
perror ("Unable to fork");
break;
} else if (child == 0) {
printf ("In child #%d\n", (i+1));
about ("Child");
break;
} else {
/* in parent */
if (waitpid(child, NULL, 0) < 0) {
perror("Failed to collect child process");
break;
}
}
}
return 0;
}
如果父项在一个或多个子项之前退出,如果它不等待就会发生,那么孩子将在其后看到其父进程为pid 1.
其他人已经回答了如何通过ps
命令获取僵尸进程列表。您也可以通过top
查看僵尸。使用原始代码,您不太可能看到僵尸的一瞥,因为父进程很快退出,init
将清除它留下的僵尸。
答案 1 :(得分:1)
你怎么知道(和)将“wait()”语句放在哪里杀死 僵尸进程?
您可以在父进程中的任何位置使用wait()
,当子进程终止时,它将从系统中删除。放在哪里取决于您,在您的具体情况下,您可能希望在child = fork();
行之后立即放置它,以便父进程在其子进程退出之前不会恢复执行。
如果你有Linux虚拟盒,查看僵尸进程的命令是什么?
您可以使用ps aux
命令查看系统中的所有进程(包括僵尸进程),如果进程是僵尸,STAT
列将等于Z
。输出示例如下:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
daniel 1000 0.0 0.0 0 0 ?? Z 17:15 0:00 command
答案 2 :(得分:0)
你怎么知道(和)将“wait()”语句放在哪里杀死 僵尸进程?
您可以为SIGCHLD注册信号处理程序,将全局volatile sig_atomic_t flag = 0
变量设置为1.然后,在程序中的某个方便的位置,测试flag
是否设置为1,如果是, ,将它设置回0然后(否则你可能会错过一个信号)在循环中调用waitpid(-1, NULL, WNOHANG)
,直到它告诉你不再需要等待进程。请注意,该信号将使用EINTR中断系统调用,这是检查flag
值的良好条件。如果您使用无限期阻止系统调用select()
,则可能需要指定超时后检查flag
,否则您可能会错过上次{{1}之后引发的信号}在进入无限期阻塞系统调用之前调用。此kludge的替代方法是使用waitpid()
。
答案 3 :(得分:0)
使用:
ps -e -opid,ppid,pgid,stat,etime,cmd | grep defunct
可以看到您的僵尸,ppid
和pgid
可以看到父级ID和进程组ID。 etime
查看您的僵尸还活着经过的时间(cpu)。父ID对于将自定义信号发送到父进程很有用。
如果父进程的编码正确,可以捕获并处理SIGCHLD
信号,并达到预期的效果(即,等待/收起僵尸),则可以提交:
kill -CHLD <parent_pid>
告诉父母收割所有僵尸。