【问题标题】:Process doesn't unpause when receiving a user-defined signal接收到用户定义的信号时进程不会取消暂停
【发布时间】:2016-12-09 17:31:59
【问题描述】:

我试图让两个进程在 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)。程序终止,但一个进程卡在后台。我究竟做错了什么?

【问题讨论】:

  • 你有这些信号的信号处理器吗?来自man pausepause() 导致调用进程(或线程)休眠,直到发出终止进程或导致调用信号捕获函数的信号。
  • 从同一个手册页中,sigsuspend(2) 可能值得一看。
  • 我以为pause() 自己捕捉到了信号……不是吗?
  • man 页面非常清晰,不是吗?

标签: c unix signals fork pause


【解决方案1】:

@尤金·肖。是正确的:你需要一个信号处理函数。 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 中打印一条消息或做其他事情,你当然可以这样做,但我读过的一般建议是让你的处理程序尽可能简单。

(顺便说一句,我还会在每个printf 之后添加fflush 调用,以确保调试时的安全。我认为这不应该是必要的,但它不会受到伤害!)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-12
    • 2013-07-20
    • 2022-01-06
    • 2021-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多