2012-12-06 46 views
4

我试图从子进程运行闪烁命令行。 例如是这样的:linux fork - execl,执行的进程变成僵尸

int hangup() { 
write_on_display("line3", "   "); 
write_on_display("hide_icon", "DIALTONE"); 
write_on_display("hide_icon", "BACKLIGHT"); 

int pid = fork(); 
if (pid == 0) { 
    int res = execl("/usr/bin/twinkle", " ", "--immediate", "--cmd", 
      "answerbye", (char *) NULL); 
    _exit(0); 
} else { 
    perror("hangup"); 
    return 0; 
} 
return 1; 
} 

但闪烁变得僵尸:

10020 pts/1 Z+  0:00 [twinkle] <defunct> 
10040 pts/1 Z+  0:00 [twinkle] <defunct> 
10053 pts/1 Z+  0:00 [twinkle] <defunct> 
10064 pts/1 Z+  0:00 [twinkle] <defunct> 
10097 pts/1 Z+  0:00 [twinkle] <defunct> 
10108 pts/1 Z+  0:00 [twinkle] <defunct> 
10130 pts/1 Z+  0:00 [twinkle] <defunct> 

我试图设置 信号(SIGCHLD,SIG_IGN); 但没有成功。 其实我觉得孩子的过程在闪烁之前就消失了。

从类似的命令行运行闪烁:

twinkle --immediate --call 100 

不作僵尸 - 闪烁关闭正常。 我在那里失踪了什么?

回答

7

父进程需要调用waitpid()与子进程ID。从链接的参考页面:

所有这些系统调用都用于等待调用进程的子进程中的状态更改,并获取有关状态已更改的子进程的信息。状态变化被认为是:孩子终止;孩子被一个信号阻止了;或者这个孩子被一个信号恢复了。 在终止的孩子的情况下,执行等待允许系统释放与孩子相关的资源;如果未执行等待,则终止的孩子保持在“僵尸”状态(参见下面的注释)。

例如:

pid_t pid = fork(); 
if (0 == pid) 
{ 
    /* Child process. */ 
} 
else 
{ 
    /* Parent process, wait for child to complete. */ 
    int status; 
    waitpid(pid, &status, 0); 
} 
+0

仅有旁注:IIRC,execl'后'代码将*不*被除非'execl'产生错误执行。 – Jite

+0

@Jite,正确。 exit(0);'_disappears_如果'execl()'成功。 – hmjd

2

是的,但我需要父母和孩子的工作同步。

其实我发现了我的错误。 所以,如果有人有类似的问题,像这样的信号处理函数:

void catch_child(int sig_num) 
{ 
    /* when we get here, we know there's a zombie child waiting */ 
    int child_status; 

    wait(&child_status); 

} 

和 信号(SIGCHLD,catch_child)

在main()函数 一切正常

PP 这里: is a very good explanation.

+0

这是一个好主意,可以在父进程中捕获“子进程结束”信号,并在那里“等待”它。它真的有用吗? –