根据上一个任务的 sigchld() 执行新任务

发布于 2024-12-15 05:17:16 字数 886 浏览 2 评论 0原文

我目前正在 C++ 中构建一个小型 shell。

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

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

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

上述所有操作都需要能够在后台发生,我希望避免让 jobManager 忙于等待 exe1 返回。我也不希望有一个单独的线程只是等待开始另一个进程的执行。但是,指示我的 jobManager 从 SIGCHLD 处理程序开始执行下一个进程似乎是糟糕的代码。

任何反馈都会被采纳。

I'm currently in the process of building a small shell within C++.

A user may enter a job at the prompt such as exe1 && exe2 &. Similar to the BASH shell, I will only execute exe2 if exe1 exits successfully. In addition, the entire job must be performed in the background (as specified by the trailing & operator).

Right now, I have a jobManager which handles execution of jobs and a job structure which contains the job's executable and their individual arguments / conditions. A job is started by calling fork() and then calling execvp() with the proper arguments. When a job ends, I have a signal handler for SIGCHLD, in which I perform wait() to determine which process has just ended. When exe1 ends, I observe its exit code and make a determination as to whether I should proceed to launch exe2.

My concern is how do I launch exe2. I am concerned that if I use my jobManager start function from the context of my SIGCHLD handler, I could end up with too many SIGCHLD handler functions hanging out on the stack (if there were 10 conditional executions, for instance). In addition, it just doesn't seem like a good idea to be starting the next execution from the signal handler, even if it is occurring indirectly. (I tried doing something similar 1.5 years ago when I was just learning about signal handling -- I seem to recall it failing on me).

All of the above needs to be able to occur in the background and I want to avoid having the jobManager sitting in a busy wait just waiting for exe1 to return. I would also prefer to not have a separate thread sitting around just waiting to start the execution of another process. However, instructing my jobManager to begin execution of the next process from the SIGCHLD handler seems like poor code.

Any feedback is appriciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

同展鸳鸯锦 2024-12-22 05:17:16

我看到两种方法:
1)用调用“sigwait”的循环替换ighandler(参见 man 3 sigwait)
然后在循环

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

I see two ways:
1)Replace you sighandler with loop that call "sigwait" (see man 3 sigwait)
then in loop

2)before start create pipe, and in mainloop of your program use "select" on pipe handle to wait
events. In signal handler write to pipe, and in mainloop handle situation.

面如桃花 2024-12-22 05:17:16

嗯,这是一件好事。

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

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

Hmmm that's a good one.

What about forking twice, once per process? The first one runs, and the second one stops. In the parent SIGCHLD handler, send a SIGCONT to the second child, if appropriate, which then goes off and runs the job. Naturally, you SIGKILL the second one if the first one shouldn't run, which should be safe because you won't really have set anything up.

How does that sound? You'll have a process sitting around doing nothing, but it shouldn't be for very long.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文