你的问题对我来说有点不清楚,但我会提到一些我考虑过针对类似情况做的事情。
当您创建一个进程时,您可以暂时阻止SIGCHLD 并将子进程的记录(以及如何处理它)放入一个表中。
child_table_node_t * node = malloc(sizeof(child_table_node_t) );
// err check that
child_table_node_init(node, type_of_child_stuff);
sigset_t old, set;
sigemptyset(&set);
sigaddset(&set, SIGCHLD);
sigprocmask(SIG_BLOCK, &set, &old);
pid_t pid = fork();
if (pid > 0) {
node->pid = pid;
add_to_table(alive_children, node);
sigprocmask(SIG_SETMASK, &old, NULL);
// other stuff
} else {
sigprocmask(SIG_SETMASK, &old, NULL);
if (!pid) {
// do child stuff
} else {
// do parent with no child stuff
}
}
然后您的handle_sigchild 可以查找表中死亡(或停止或其他)的孩子并为他们做点什么。我建议将它们从alive_children 表中删除,并在它们死亡时将它们放入信号处理程序的dead_children 表中,以便您的应用程序可以更轻松地处理它们并释放它们的内存。如果您想跟上孩子们被阻止和死亡的步伐,那么这将变得有点复杂 b/c 您不会希望将它们从活动表中删除。仅在非信号代码中遍历表以定位更改的节点可能更容易。如果是这种情况,您可以在不阻塞信号的情况下执行此操作,除非您添加或删除了节点。
然后,您的应用程序可以根据存储在该进程的表节点中的数据执行特定于死去的孩子的操作。如果孩子在前台,那么它的死亡(或停止动作)将是将退出代码存储到退出代码变量中并再次开始从终端或脚本中获取命令。如果新死的孩子是后台进程,那么您只需记录其退出代码并在下次打印命令提示符之前将其报告给终端(如果您处于交互模式)。