使用循环等待信号的C语言代码

5

在C Linux中,是否有一种无需循环等待信号SIGUSR1SIGUSR2的方式?

例如,在这段代码中,我等待SIGUSR1SIGUSR2来打印消息,但我只能使用while true循环等待。

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

void signal_callback_handler(int signum)
{
   printf("Caught signal %d\n",signum); 
}

int main()
{
   signal(SIGUSR1, signal_callback_handler);
   signal(SIGUSR2, signal_callback_handler);
   while(1)
   {
      printf("Program processing stuff here.\n");
      sleep(1);
   }
   return EXIT_SUCCESS;
}

我该如何等待并且不执行任何操作(不使用while true)直到SIGUSR1或者SIGUSR2信号到达?

例如:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

void signal_callback_handler(int signum)
{
   printf("Caught signal %d\n",signum); 
}

int main()
{
   signal(SIGUSR1, signal_callback_handler);
   signal(SIGUSR2, signal_callback_handler);

    printf("this line happned after signal arrived \n ");
   return EXIT_SUCCESS;
}

你可以使用 select()。这是我脑海中的第一反应,因为我知道 select() 可能会永久阻塞。select(2) - Iharob Al Asimi
可能还有许多其他可行的技巧。 - Iharob Al Asimi
你可能想要阅读关于sleep的man页面。在Linux上,sleep会被信号终止。因此,你可以睡很长时间——比如几年——当你醒来时,检查一下你的信号处理程序是否已经被调用。顺便说一句,在信号处理程序中调用printf不是一个好主意;请参阅man 7 signal。 - dmuir
1
永远不要在信号处理程序中使用printf - user10678532
1个回答

7
有两种可能性:
  • pause() 或者
  • sigwait()
pause 函数的文档描述如下:

描述
pause()函数使调用进程(或线程)进入睡眠状态,直到发送一个信号来终止该进程或引起信号捕获函数的调用。

来源:https://linux.die.net/man/2/pause
sigwait函数的文档描述如下:

描述
sigwait() 函数挂起调用线程的执行,直到指定的信号集中有一个信号变成待处理状态。该函数接受该信号(从待处理信号列表中删除它),并将信号编号存储在 sig 中。

来源:https://linux.die.net/man/3/sigwait

这两个函数都符合 POSIX.1-2001标准。

1
POSIX规范:pause()sigwait()。请不要使用sigpause()——它已经过时(这意味着只应该由现有使用它的代码使用,而不是由任何新代码使用)。 - Jonathan Leffler
@JonathanLeffler 那使用 sigwait() 函数可以吗? - joif doi
1
@joifdoi:是的,使用sigwait()pause()都可以。使用sigwait()会暂停线程;而pause()函数则更古老(比线程早很多),会阻塞进程中唯一的线程。我倾向于使用pause(),因为我也比较古老;但现如今,sigwait()可能是更好的选择。它提供了更好的选择性——你可以(必须)指定你感兴趣的信号,而pause()会在接收到任何信号时返回。 - Jonathan Leffler
有不止两种可能性。poll(0, 0, -1) 是第三种。而且还有很多其他的。 - user10678532
1
请注意,sigwait()将消耗信号并且处理程序不会被调用。我建议使用sigsuspend()。 - Mark Plotnick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接