2011-07-01 47 views
1

我有一个启动4个其他二进制文件的shell脚本。我正在将SIGSTOP发送到shell脚本。这是否会阻止所有其他4个进程?如果不是,我该怎么做才能将SIGSTOP转发到这些进程? SIGCONT也是如此。如何将SIGSTOP发送到从shell脚本启动的所有进程

我有所有4个二进制文件的C源代码。

+0

我觉得SIGSTOP不能被捕获。 –

+0

shell脚本是从命令行运行的东西,还是通过'execvp'等从分叉子进程运行? – Jason

回答

5

您可以在将执行shell脚本的分叉子进程中调用setpgid()。这将为该shell脚本生成的任何衍生进程提供与子进程相同的组ID。然后您可以使用killpg()向整个组发送一个信号,该组中的所有进程都将收到信号。

例如,如果在子进程中您调用setpgid(0, 0),则会设置一个特殊实例,其中子进程的组ID将设置为与子进程的PID相同的值。然后使用exec系列函数之一覆盖子进程上的任何进程将具有该子进程的相同组ID值。另外,新覆盖的进程可能产生的任何进程也将具有相同的组ID(即,你的shell脚本)。然后,您可以使用killpg()向使用只有fork()返回的子PID的值的任何共享组ID的进程发送信号,因为子进程的组ID与子进程调用后的子PID相同。

如果您使用的是fork(),取决于您需要从父进程向组发送信号的速度有多快,可能会产生一些同步问题......例如,您希望立即将信号发送到进程组分叉子进程。对此有两种解决方法:1)使用vfork()而不是fork,以便父级暂停,直到子级更改其组ID并成功调用exec或2)在父级进程中调用setpgid()因为在子进程中,但在父进程中,而不是像在子进程中使用setgpid(0, 0)那样,可以使用setpgid(CHILD_PID, CHILD_PID)。然后,哪个呼叫成功并不重要(其中一个会成功,另一个会失败,并且EACCES),并且从父母发送的任何连续信号都会转到有效的组ID。

+0

不是组ID的专家,但是不能在同一组中有其他进程? –

+0

如果使用特殊情况'setpgid(0,0)'将进程组ID设置为与子进程ID相同的值,则该机会相当远。 – Jason

+0

考虑一个进程A启动一个shell脚本B.进程A的组ID是'G'。脚本B启动另外四个进程C,D,E和F. C,D E和F的组ID是否为'G'? – Jacob

1

如果您的过程组成一个组,您可以使用标准kill(1)。 man kill具有以下信息:

pid... 
    Specify the list of processes that kill should signal. Each pid can be one of five things: 
n 
    where n is larger than 0. The process with pid n will be signaled. 
    All processes in the current process group are signaled. 
-1 
    All processes with pid larger than 1 will be signaled. 
-n 
    where n is larger than 1. All processes in process group n are signaled. When an argument of the form '-n' is given, and it is meant to denote a process group, either the signal must be specified first, or the argument must be preceded by a '--' option, otherwise it will be taken as the signal to send. 
commandname 

在我看来,该“-n”规范可能会帮助你

kill -STOP -- "-$(pgrep myparentproc)" 
+0

我不明白这是如何代替@Jason提到的函数的,因为您首先必须将这些进程导入进程组,这是他的大部分答案描述的内容。这只会取代'killpg'调用。 –

+0

@本 - 我的意思。对不起,如果我能更清楚。我习惯于发布最少的样本,有时只增加一些密集的线条似乎会增加更多的困惑,比解决它... – sehe