【发布时间】:2019-09-11 20:53:27
【问题描述】:
在这种情况下,我有 3 个多进程,1 个父 2 个子。我希望每个孩子在从他们的信号处理程序返回后继续。但有时它们会卡住,有时只有其中一个会继续。我的错误是什么?实际上我正在尝试做一些类似于用信号唤醒的事情。我可以有更多的信号来做到这一点,但如果需要 100 个孩子怎么办?所以,我只想通过使用SIGUSR2来实现这一点
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
void tellerHandler(int sig) {
//write(STDERR_FILENO, "Teller has caught SIGUSR2 signal\n", 33);
printf("pid %u Teller has caught SIGUSR2 signal\n", getpid());
}
int main() {
int NUM_OF_CHILDREN = 2;
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_flags = 0;
sa.sa_handler = tellerHandler;
if (sigaction(SIGUSR2, &sa, NULL) == -1) {
perror("sigaction error");
exit(-1);
}
sigset_t new_mask;
sigfillset(&new_mask);
sigdelset(&new_mask, SIGUSR2);
int returnedPid = -1;
pid_t pidList[NUM_OF_CHILDREN];
for (int i = 1; i < 1 + NUM_OF_CHILDREN; ++i) {
if ((returnedPid = fork()) == 0) {
break;
} else {
pidList[i - 1] = returnedPid;
}
}
if (returnedPid == 0) {
sigsuspend(&new_mask);
printf("child %u returned from handler\n", getpid());
} else {
for (int i = 0; i < NUM_OF_CHILDREN; ++i) {
printf("child %u\n", pidList[i]);
kill(pidList[i], SIGUSR2);
}
for (int i = 0; i < NUM_OF_CHILDREN; ++i) {
waitpid(pidList[i], 0, 0);
}
puts("parent exiting...\n");
}
puts("donee");
}
多次运行的一些不同输出,
child 66313
child 66314
pid 66313 Teller has caught SIGUSR2 signal
child 66313 returned from handler
pid 66314 Teller has caught SIGUSR2 signal
---
child 66330
child 66331
pid 66330 Teller has caught SIGUSR2 signal
pid 66331 Teller has caught SIGUSR2 signal
---
当我将孩子人数增加到 3 时,以下输出类似于
child 66738
child 66739
child 66740
pid 66739 Teller has caught SIGUSR2 signal
pid 66738 Teller has caught SIGUSR2 signal
child 66738 returned from handler
donee
pid 66740 Teller has caught SIGUSR2 signal
【问题讨论】:
-
printf在信号处理程序中调用是不安全的。 -
你为什么打电话给
sigsuspend? -
@WilliamPursell 先生,这只是我卡住的代码的一小部分。我用它来同步。
-
@WilliamPursell printf 只是为了测试