向儿童流程发送信号,Sigcont,Sigstop
我的代码有问题,
我希望所有孩子在程序启动时停止。 之后,我只希望带有i
索引的孩子继续执行,而其他孩子则被停止。
我想在此顺序p0,p1,p2,p3,p4,p0,p1中执行它们。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#define N 5
void handler(int i)
{
if (i == SIGCONT)
{
printf("signal cont\n");
}
}
int main()
{
int pid[N];
for (int i = 0; i < N; i++)
{
if ((pid[i] = fork()) == 0)
{
/* code */
while (1)
{
printf("ici fils %d\n", i);
usleep(50000);
}
}
else
{
kill(pid[i], SIGSTOP);
// kill(pid[i], SIGSTOP);
if (i == N - 1)
{
kill(pid[i], SIGCONT);
sleep(2);
kill(pid[i], SIGSTOP);
kill(pid[0], SIGCONT);
}
else
{
kill(pid[i], SIGCONT);
sleep(2);
kill(pid[i], SIGSTOP);
kill(pid[i + 1], SIGCONT);
}
// kill(pid[i], SIGKILL);
waitpid(pid[i], NULL, 0);
}
signal(SIGCONT, &handler);
}
}
I have a problem with my code,
I want all the children stop when the program start.
and after that I want just the child with the index of i
to continue executing and others to be stopped .
I want to execute them in this order p0 ,p1,p2,p3,p4,p0,p1....
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#define N 5
void handler(int i)
{
if (i == SIGCONT)
{
printf("signal cont\n");
}
}
int main()
{
int pid[N];
for (int i = 0; i < N; i++)
{
if ((pid[i] = fork()) == 0)
{
/* code */
while (1)
{
printf("ici fils %d\n", i);
usleep(50000);
}
}
else
{
kill(pid[i], SIGSTOP);
// kill(pid[i], SIGSTOP);
if (i == N - 1)
{
kill(pid[i], SIGCONT);
sleep(2);
kill(pid[i], SIGSTOP);
kill(pid[0], SIGCONT);
}
else
{
kill(pid[i], SIGCONT);
sleep(2);
kill(pid[i], SIGSTOP);
kill(pid[i + 1], SIGCONT);
}
// kill(pid[i], SIGKILL);
waitpid(pid[i], NULL, 0);
}
signal(SIGCONT, &handler);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的代码有几个问题,其中包括:
通过
sigstop
停止的任何进程一定不得注册该信号的处理程序。注册处理程序会使处理程序的行为替换 停止过程的默认行为。注册
sigcont
的处理程序通常是个坏主意。这样做不会阻止sigcont
继续进行该过程,这是sigcont
的特殊特征,这可能令人惊讶,但是每当sigcont时,处理程序也会发射
也可以交付,即使该过程没有停止,这通常是另一种惊喜。您仅在第一个叉子后才在父级中注册信号处理程序。后来分叉的孩子将继承这些孩子,但第一个不会。除其他外,这将阻止第一个孩子的
pape()
不受父母发送给它的信号的阻止。您可以将每个孩子自行注册任何需要的处理程序,也可以在第一个叉子之前在父母中注册。。
每个孩子的
pape()
与父母的第一个kill()
针对该孩子的比赛。孩子可以在调用pause()
之前接收sigcont
,在这种情况下,它将等待 next 信号。您可以通过在分叉之前在父级中阻止sigcont
,并使用适当的掩码在子里使用sigsuspend()
,而不是初始暂停( )
。在这种情况下,您可能要解开sigcont
从该初始sigsuspend()
。。父母试图向尚未分配的进程发送信号(
kill(pid [i + 1],sigcont);
)。目前尚不清楚您要实现的全部行为是什么,但是您可能要先求所有孩子,然后才开始发送信号。
更新
关于对问题的更新,
There are several issues with your code, among them:
Any processes to be stopped via
SIGSTOP
must not have a handler registered for that signal. Registering a handler causes the handler's behavior to replace the default behavior of stopping the process.It's usually a bad idea to register a handler for
SIGCONT
. Doing so will not prevent aSIGCONT
from continuing the process, which is a special characteristic ofSIGCONT
that can be surprising, but also the handler will fire whenever aSIGCONT
is delivered, even if the process was not stopped, which is often a different kind of surprise.You register your signal handlers only in the parent, after the first fork. The subsequently forked children will inherit those, but the first one will not. Among other things, this will prevent the first child's
pause()
from being unblocked by the signals the parent sends to it. You can make each child register any needed handlers for itself, or you can register them in the parent, before the first fork.There is a race between each child's
pause()
and the parent's firstkill()
targeting that child. It is possible for the child to receive theSIGCONT
before it callspause()
, in which case it will wait for the next signal. You can prevent that by blockingSIGCONT
in the parent before forking, and usingsigsuspend()
in the child, with an appropriate mask, instead of the initialpause()
. In that case, you probably want to unblockSIGCONT
after returning from that initialsigsuspend()
.The parent attempts to send signals to processes that it has not forked yet (
kill(pid[i + 1], SIGCONT);
).It's not clear what the full behavior you are trying to achieve is, but you may want to fork all the children first, and only then start sending signals.
Update
With respect to the update to the question,
在 child 过程中,而不是使用 <代码>暂停(2) ,使用
提高(3)
发出通话过程,以停止使用sigstop
。无需注册信号处理程序。在 parent 过程中,创建 child 进程后,请使用
waitpid(2)
带有wuntraced
flag设置。wifstopped(...)
宏可用于专门确定孩子的状态。wcontinue
标志可用于等待 child 继续进行,就像在有wifcontinued(...)
宏观之前一样。这是一个粗略的示例,没有有意义的错误处理。请注意,同时睡觉虽然很简单,但从技术上讲,这并不是安排事物的一致方法。在执行之间,该程序的输出 May 略有不同。
In the child processes, instead of using
pause(2)
, useraise(3)
to signal the calling process to stop withSIGSTOP
. There is no real need to register signal handlers.In the parent process, after creating a child process, wait for it to stop (or terminate) by using
waitpid(2)
with theWUNTRACED
flag set. TheWIFSTOPPED(...)
macro can be used to specifically determine the status of the child. TheWCONTINUE
flag can be used to wait for a child process to continue, and like before there is theWIFCONTINUED(...)
macro.Here is a cursory example, with no meaningful error handling. Note that concurrent sleeps, while simple, are not technically a consistent way to schedule things. The output of this program may differ slightly between executions.