c - 如何在后台执行僵尸进程后避免它们

标签 c shell background

我们正在用 C 编写一个类似 bash 的 shell,但我们在后台进程方面遇到了问题。 问题是当没有 & 时,父亲会等待子进程,我们为 SIGCHLD 创建了一个 signal_handler,里面有一个等待。

我们要避免的主要问题是:signal_handler一直执行(有后台和前台进程),所以如果signal_handler在父进程之前捕获到SIGCHLD,那么父亲的等待没有 child 等待,所以它返回一个错误。

我们取决于他们中的谁在之前执行,我们希望如果没有并且 signal_handler wait 不会在父亲之前收集 child 。

任何帮助都至关重要。非常感谢。

最佳答案

你的问题对我来说有点不清楚,但我会提到一些我在类似情况下考虑过的事情。

当您创建一个进程时,您可以暂时阻止 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 然后可以在表中查找死亡(或停止或其他)的 child 并为他们做一些事情。我建议将它们从 alive_children 表中移除,并在它们死亡时将它们放入信号处理程序中的 dead_children 表中,以便您的应用程序可以更轻松地处理它们并释放它们的内存。如果您想跟上 child 被停止和死亡的情况,那么这将变得更加复杂 b/c 您不想将它们从事件表中删除。在非信号代码中遍历表以定位更改的节点可能更容易。如果是这种情况,您可以在不阻塞信号的情况下执行此操作,除非您添加或删除了节点。

然后,您的应用程序可以根据存储在该进程的表节点中的数据,针对已死亡的 child 执行特定操作。如果 child 在前台,那么它的死亡(或停止 Action )将是将退出代码存储到退出代码变量中,并再次开始从终端或脚本接收命令。如果新死的 child 是后台进程,那么您只需记录它的退出代码并在下次打印命令提示符(如果您处于交互模式下)之前将其报告给终端。

关于c - 如何在后台执行僵尸进程后避免它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2881119/

相关文章:

c - 嵌入式函数指针

c - 如何访问二维数组的外边界元素?

c - C 中的递归合并排序和内存分配

c - 如何调用另一个程序并通过 $ 获取返回值?

linux - bash中的shell脚本从ftp服务器下载文件

c - 函数没有 return 语句返回值

Linux - 在一定时间内重复执行一条命令

html - x-repeating 背景图像未完全展开

android - 如何同时为android布局元素的背景使用形状和选择器?

swift - 尽管启用了后台位置更新,但 CLLocationManager 委托(delegate)在应用程序暂停后未收到位置更新