我试图让两个进程在C中合作。为此,我使用pause()
和用户信号,正如我的理解,pause()
导致程序进入睡眠状态直到收到信号。我这样做:
pid_t child = fork();
if(child < 0) {
perror("Fork error");
exit(1);
}
else if (child > 0) { //parent process
//do something here, then:
printf("Parent pausing\n");
pause();
printf("parent received sigusr2\n");
//do something
kill(child, SIGUSR2);
printf("Sent signal to child\n");
sleep(1);
fflush(NULL);
pause();
kill(child,SIGTERM);
waitpid(child, &status, 0);
}
else { //child process
//do something, then
printf("Child sending sigusr2\n");
kill(getppid(), SIGUSR2);
printf("Child pausing\n");
pause();
//do something
kill(getppid(), SIGUSR2);
fflush(NULL);
printf(frompipe);
pause();
}
(这可能会在之后出现问题我所显示的具体问题,但尚未在编码中获得)。所以我目前的输出是:
Parent pausing
Child sending sigusr2
Child pausing
User-defined signal 2
它就在那里停止,好像父进程没有收到信号(因为它没有打印parent received sigusr2
)。程序终止,但进程陷入后台。我究竟做错了什么?
答案 0 :(得分:1)
@Eugene Sh。是正确的:你需要一个信号处理函数。 pause(2)
man page说
pause()仅在捕获到信号并返回信号捕获函数时返回。
要使用sigaction(2)
执行此操作,请添加到您的程序中:
void sigusr2_handler(int) { /* do nothing*/ }
然后,在fork()
来电之前,添加
struct sigaction sa;
sa.handler = sigusr2_handler;
sa.mask = 0;
sa.sa_flags = 0;
sigaction(SIGUSR2, sigusr2_handler);
使用sigaction
表示此处理程序将一直存在,直到您将其禁用(与signal(2)
不同)。在fork
电话会议之前将其设置为适用于父母和孩子; the man page说:“通过fork(2)
创建的子项会继承其父级信号处置的副本。”
使用此代码,您的pause()
电话应该返回。如果您想在sigusr2_handler
内打印消息或做其他事情,您当然可以这样做,但我读过的一般建议是让您的处理程序尽可能简单。
(顺便说一下,我还会在每个fflush
之后添加printf
次调用,以便在调试时保持安全。我认为这不应该是必要的,但它不会受到伤害! )