从前一个任务执行基于sigchld()的新任务

时间:2011-11-13 01:16:23

标签: c++ shell fork signals process-management

我目前正在使用C ++构建一个小shell。

用户可以在exe1 && exe2 &等提示下输入作业。与BASH shell类似,如果exe2成功退出,我将只执行exe1。此外,整个作业必须在后台执行(由尾随&运算符指定)。

现在,我有一个处理作业执行的jobManager和一个job结构,其中包含作业的可执行文件及其各自的参数/条件。通过调用fork()然后使用正确的参数调用execvp()来启动作业。当作业结束时,我有SIGCHLD的信号处理程序,我在其中执行wait()以确定哪个进程刚刚结束。当exe1结束时,我会观察其退出代码,并确定是否应继续启动exe2

我关心的是如何启动exe2。我担心如果我从我的SIGCHLD处理程序的上下文中使用我的jobManager启动函数,我可能最终会在堆栈上挂出太多SIGCHLD处理程序函数(如果有10个条件执行,例如)。另外,从信号处理程序开始下一次执行似乎不是一个好主意,即使它是间接发生的。 (我在1.5年前尝试做类似的事情,当时我正在学习信号处理 - 我似乎记得它在我身上失败了。)

以上所有需要能够在后台进行,我希望避免让jobManager坐在忙碌的等待中exe1等待返回。我还希望没有一个单独的线程,只是等待开始执行另一个进程。但是,指示我的jobManagerSIGCHLD处理程序开始执行下一个进程似乎是糟糕的代码。

任何反馈都是适当的。

2 个答案:

答案 0 :(得分:1)

我看到两种方式:
1)用称为“sigwait”的循环替换你的sighandler(见man 3 sigwait)
然后在循环中

2)在开始创建管道之前,在你的程序的主循环中使用管道句柄上的“select”来等待 事件。在信号处理程序中写入管道,并在mainloop处理情况。

答案 1 :(得分:0)

嗯,这是一个很好的。

两次分叉,每个过程一次?第一个运行,第二个停止。在父SIGCHLD处理程序中,如果适用,将SIGCONT发送给第二个子节点,然后该节点将关闭并运行该作业。当然,如果第一个不应该运行,你可以SIGKILL第二个,这应该是安全的,因为你不会真正设置任何东西。

听起来怎么样?你将有一个无所事事的过程,但它不应该持续很长时间。