【发布时间】:2012-07-21 15:30:09
【问题描述】:
我正在对 fork()、exec() 和相关的 UNIX 调用进行分配,我需要在这些调用中显示(子)进程的僵尸状态。这是相关的代码:
pid = vfork(); //used vfork() for showing z state
if(pid>0)
{
(some sorting code)
execl("/bin/ps","/bin/ps","a",(char*)0);
}
我的期望是:
(child's output)
(parent's output)
(Output of the ps command where I then would be able to show a 'defunct' entry)
我得到的是:
(child's output)
(parent's output)
No ps command output. Instead I get: Signal 17 (CHLD) caught by ps (procps version 3.2.8)
但是,当在 execl 调用之前插入 sleep(int time)(以秒为单位的整数时间)时,我得到了所需的输出并且没有报告任何信号错误。
这里发生了什么? ps 是否成为(尚未成为僵尸的)孩子的新父母?
为什么ps 命令不执行? sleep() 做了什么使 ps 按要求执行?
我是 POSIX/Linux 编程的新手,因此我将不胜感激此 SIGCHLD 信号与我的特定情况的任何相关性。谢谢!
【问题讨论】:
-
什么是“(一些排序代码)”?如果它有任何可能触发系统调用,它可能是不安全的或至少是未定义的。通常你只能做琐碎的事情(例如,一堆不分配内存或调用操作系统的计算),然后再调用一个孩子的
execXX()函数。 -
(一些排序代码)只是整数数组的选择排序代码。没有使用任何其他系统调用,没有指针,malloc() 也没有。
-
@KevinGrant:
vfork(),是的。用普通的fork(),没有。 -
它可能取决于 UNIX 变体,但我肯定见过普通的
fork()版本,其中包含儿童可以做什么的警告。 -
请注意,一般情况下,在
vfork()孩子中唯一安全的做法是调用exec*()、_exit()和/或修改pid_t类型的变量以存储结果的vfork()。如果您想等待孩子,请使用fork()和wait*()系列函数之一。
标签: linux unix exec fork sigchld