[英]C Can't signal a child process to continue after `sigsuspend`
我正在尝试创建一个程序,其中一个进程分叉,创建一个子进程,并且父进程必须始终在子进程完成打印到屏幕之前完成打印到屏幕,无论如何。 我也希望使用信号而不是流水线来实现这一点。
这是一个与这里提出的问题类似的问题: 需要 sigsuspend 的解释
我明白kill(pid,signal);
是向该 pid 发送信号并告诉它完成执行并终止。
问题是,当它执行时,子进程在挂起后不会打印。 代码如下:
int main(void){
pid_t pid;
int i;
pid = fork();
if(pid==0){
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask,SIGUSR1);
printf("This is the child Process id = %d \n",getpid());
sigsuspend(&mask);
printf("The child is now complete \n");
}
else{
printf("This is the parentProcess id = %d \n",getpid());
printf("The parentProcess is complete\n");
sleep(1);
int j = kill(pid,SIGUSR1);
if (j!=0)
{
perror(NULL);
}
exit(0);
}
}
我设法通过使用全局变量int x = 0;
完成了我的任务(在孩子之前打印父母) int x = 0;
和信号处理方法void handle1(int s){x = 1;}
在 main 之前。 在主要我添加了signal(SIGUSR1,handle1);
在孩子中,我删除了所有 sigset 和 sigsuspend 行,而是在printf
语句之前写了while(x==0){/*do_nothing*/}
1 行。 因此,当父进程执行kill(pid,SIGUSR1)
,子进程继承的信号处理程序也会被执行并设置 x=1。 所以孩子现在离开while循环并可以打印它的语句。
但是我相信知道如何使用sigmask_t
和sigsuspend()
完成这项任务会很有帮助,但我无法让它以这种方式工作。
你有几个问题。
您的父进程应该等待子进程完成。 这允许诊断(例如正确等待孩子打印),但在其他方面是一个簿记任务,即使等待进程将退出,也是一个好习惯:
printf("This is the parentProcess id = %d \n",getpid());
printf("The parentProcess is complete\n");
sleep(1);
int j = kill(pid,SIGUSR1);
if (j!=0)
{
perror(NULL);
exit(0);
}
waitpid(pid, NULL, 0);
exit(0);
现在,您已将掩码中的SIGUSR1
设置为sigsuspend()
,这会导致信号被忽略。 一旦父级等待,这现在更加明显,因为父级永远不会退出。 因此,删除设置SIGUSR1
的代码行。
最后, SIGUSR1
的默认处理程序只会导致进程退出,因此printf
将没有机会打印。 如果你想打印它,你应该为SIGUSR1
添加一个信号处理程序。 它不必做任何事情。
void h (int s) {}
...
sigset_t mask;
sigemptyset(&mask);
//sigaddset(&mask,SIGUSR1);
printf("This is the child Process id = %d \n",getpid());
struct sigaction sa = { .sa_handler = h };
sigaction(SIGUSR1, &sa, NULL);
sigsuspend(&mask);
printf("The child is now complete \n");
您的代码中有 3 个问题:
SIGUSR1
是你想传递给孩子的信号。 你不能使用sigaddset(&mask,SIGUSR1);
,它与您的意图完全相反。
根据下面的 POSIX 标准sigsuspend()
,您应该为SIGUSR1
安装一个信号处理程序,以使sigsuspend()
继续以下代码,因为SIGUSR1
的默认行为是终止。
sigsuspend() 函数应该用 sigmask 指向的一组信号替换调用线程的当前信号掩码,然后挂起线程直到传递一个信号,该信号的动作是执行信号捕获函数或终止进程.
下面的代码将起作用:
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
void handler(int sig) {}
int main(void){
pid_t pid;
int i;
pid = fork();
signal(SIGUSR1, handler);
if(pid==0){
sigset_t mask;
sigemptyset(&mask);
//sigaddset(&mask,SIGUSR1);
printf("This is the child Process id = %d \n",getpid());
sigsuspend(&mask);
printf("The child is now complete \n");
}
else{
printf("This is the parentProcess id = %d \n",getpid());
printf("The parentProcess is complete\n");
sleep(1);
int j = kill(pid,SIGUSR1);
if (j!=0)
{
perror(NULL);
}
wait(NULL);
exit(0);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.