信号未按预期工作(C 语言、linux)



我试图回答这个问题:

编写一个创建两个子级的程序 C。第二个子进程 被阻止,直到接收到信号SIGUSR1从 父进程。虽然第一个子进程被阻止,直到 SIGUSR2接收从 第二个子进程。终止后终止父级 他的孩子。

但是,执行在下面的代码中没有按预期工作,并且仅显示父printf。你能告诉我我的代码有什么问题吗?

我的代码:

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <signal.h>
void this(int sig) {
printf("this is this");
}
int main() {
int pid = fork();
int pid2;
if (pid < 0) {
exit(-1);
} else if (pid == 0) {
printf("FIrst child is paused");
pause();
printf("ERror");
} else {
pid2 = fork();
if (pid2 < 0) {
exit(-2);
} else if (pid2 == 0) {
signal(SIGUSR1, &this);
printf("Second child is paused");
pause();
kill(pid,SIGUSR2);
printf("signal sent to first child");
} else {
printf("this is the parent");
kill(pid2, SIGUSR1);
printf("signal sent to second child");
wait(NULL);
exit(-3);
}
}
} 

您没有做出任何规定来确保仅当第二个孩子准备好时,才会将父母的信号传递给第二个孩子。 由于进程启动需要一些时间,因此信号确实会更快地传递。 在这种情况下,第二个子项将被终止(默认处置SIGUSR1),或者它将在pause()中无限期阻塞(如果在安装处理程序之后但在pauseing 之前收到信号)。 在这两种情况下,第二个孩子都不会向第一个孩子发出信号。

信号掩码和信号处置是通过分叉继承的,因此您可以通过在分叉之前阻止父级中的SIGUSR1来解决这个问题,然后在子级中使用sigsuspend()而不是pause(),这将使您能够原子地取消阻塞信号并开始等待它。

对于第一个孩子来说,这不是问题,因为您正在寻找它来执行SIGUSR2(终止)的默认处置,并且对于指定的行为,无论这发生在该孩子到达或阻止之前pause()都无关紧要。

<小时 />

此外,

  • 父母只等待一个孩子,但提示似乎说它必须等待两个孩子。 也许你放弃了第二个wait(),因为父母没有终止,但如果是这样,那就是其中一个孩子没有终止的缺失线索。

  • printf不是异步信号安全的,因此从信号处理程序调用它会调用未定义的行为。

  • 您应该在printf格式的末尾放置换行符。 这将使您的输出更具可读性,并且还将确保输出及时传递到屏幕。 这最终可能会在您调试时有用。 或者,使用puts()而不是printf(),因为您只输出固定字符串。puts()将自动添加换行符。

    没有换行符可能解释了为什么第一个孩子在pauses 之前的输出永远不会打印。 如果第二个孩子达到无限期pause状态,那么这也解释了为什么那个孩子的pause前输出没有被打印出来。

相关内容

  • 没有找到相关文章

最新更新