C:Exec / fork>已解散的流程

时间:2011-07-16 15:16:07

标签: c exec fork defunct

我想使用fork>创建很多子进程。执行程序。许多过程都以非常快的速度结束(不到两分钟,有些甚至更早)。

我的第一个问题是,我用

将生成过程放到后台
./spawnbot > logging.txt
[CTRL+Z]
bg 1
disown

到目前为止一切顺利。现在我不再看到任何spawnbot的消息,他们直接进入logging.txt。然而,每当创建一个新的孩子时,我再次在我的控制台中看到关于那个孩子的所有信息..我现在想要用它自己的管道启动每个孩子 - 是否有更好的方法让孩子们在他们的输出消息全部发布安慰?我应该将它重定向到/ dev / null还是用C中的一些标志完成?

其次,所有的孩子都没有真正被杀。我的ps -ef中有很多进程。我该怎么办?我该怎么做

2 个答案:

答案 0 :(得分:18)

首先是你的第二个问题!

您的孩子仍处于“僵尸”模式,因为内核认为您可能仍希望从中检索返回值。

如果您无意从子进程获取返回值,则应将父进程中的SIGCHLD信号处理程序设置为SIG_IGN,以使内核自动收获您的子进程。

signal(SIGCHLD, SIG_IGN);

第一个问题取决于你的实施..

但一般来说,就在fork()之后,你应该使用close()来关闭0和1的旧文件描述符,然后使用dup2()将它们设置为你想要的值。没时间现在举个例子,但是希望这会把你推向正确的方向..

答案 1 :(得分:14)

你的孩子进程被杀了。 Defunct processes也称为zombie processes;僵尸死了!僵尸进程只不过是进程表中的一个条目,它没有任何代码或内存。

当进程死亡(通过调用_exit或被信号杀死)时,它必须由其父进程获取。除了进程表中的条目之外,进程使用的每个资源都会消失。家长必须致电waitwaitpid。一旦父母被告知子进程的死亡,并且有机会阅读孩子的退出状态,孩子在进程表中的条目也会消失:僵尸被收获。

如果您不想收到孩子死亡的通知,请忽略SIGCHLD信号;这告诉内核你不想知道你孩子的命运,僵尸会被自动收获。

signal(SIGCHLD, SIG_IGN)

如果您只想在特定情况下收到有关您孩子死亡的通知,请使用SA_NOCLDWAIT标记致电sigaction。当一个孩子去世时,如果父母正在执行wait一系列职能,则会通知孩子的死亡并被告知退出状态;否则孩子的退出状态将被丢弃。

struct sigaction sa;
sa.sa_handler = &my_sigchld_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_NOCLDWAIT;
sigaction(SIGCHLD, &sa, NULL);

关于输出,您的孩子会写入与父级相同的位置,除非您明确重定向它们(使用closeopen,或dup或其他一些可能性)。您的孩子可能正在将诊断消息打印到标准错误(毕竟这就是它的用途)。

./spawnbot >logging.txt 2>&1

此外,由于您似乎想要从终端分离孩子,您可能希望确保他们在终止终端时没有收到SIGHUP。所以使用nohup

nohup ./spawnbot >logging.txt 2>&1 &
disown