虽然没有收到信号?

Posted

技术标签:

【中文标题】虽然没有收到信号?【英文标题】:While signal not received? 【发布时间】:2014-12-02 23:29:56 【问题描述】:

所以我最近一直在用 C 编程并研究信号和 POSIX 线程。我知道我可以等待线程中的信号,但我一直想知道是否有可能有一个包含 while 循环的线程,该循环将在未收到 SIGINT 时永远执行。 所以基本上我不是在等待信号(停止执行while循环),而是继续执行直到收到信号。只是在听某个信号。

我尝试谷歌搜索但无济于事。

有什么建议吗?提前致谢!!

【问题讨论】:

正如@xbug 所示,虽然等待信号是安全且可预测的,但它并不是处理信号的原始方式。程序在启动过程中可以注册少量的信号处理程序,只要信号到达,操作系统就会停止你的程序并直接跳转到相应的处理程序中,无论你的程序处于什么状态!在信号处理程序中清理并优雅退出可能有点困难。 pause()--挂起线程直到收到信号?它避免了忙于等待,并且在被中断之前不会返回(通过某些信号;您会确保 SIGINT 进入您的线程)?如果您希望线程在等待信号到达时做一些其他工作,这不是解决方案,但如果线程在信号到达之前什么都不做,这是等待信号到达的最佳方式。 @JonathanLeffler 但问题是,线程必须不断生成数据并将它们存储到堆中,因此不能等待。 :P 那么pause() 不是您问题的答案。 【参考方案1】:

只使用一个简单的信号处理程序怎么样?

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

static void sigint_handler( int signum );
volatile static int done = 0;

int main( int argc, char *argv[] )

   if( signal( SIGINT, sigint_handler ) == SIG_ERR ) 
      perror( "signal()" );
      exit(1);
   

   while( !done ) 
      (void)printf( "working...\n" );
      (void)sleep( 1 );
   

   (void)printf( "got SIGINT\n" );

   return 0;


void sigint_handler( int signum )
 done = 1; 

编辑:使 done 不稳定,感谢 Joseph Quinsey 在 cmets 中指出这一点。相关讨论见this question,另见this article。

【讨论】:

注册信号处理程序可能会失败。需要检查返回值signal(SIGINT, sigint_handler)SIG_ERR 太棒了!非常感谢你!!!这太棒了 :D 但是定义全局变量不是不安全的吗?如果有人可以调整该变量,代码将在 while 循环退出时关闭。有没有更安全的方法来实施这种方法? 我不确定您所说的“不安全”是什么意思;该变量被声明为static,因此对于该文件之外的任何内容都不可见(参见this answer 中的案例#2)。那个“某人”必须在进程地址空间内,并且知道链接器甚至没有导出的变量的运行时地址,所以它非常安全(没有优雅)。 【参考方案2】:

您可以阻止该信号,然后使用具有零超时的sigtimedwait() 来轮询它。

在主线程中,在创建任何其他线程之前,阻塞SIGINT。随后创建的线程会继承信号掩码,所以SIGINT会在所有线程中被阻塞:

sigset_t sigint_set;

sigemptyset(&sigint_set);
sigaddset(&sigint_set, SIGINT);    
sigprocmask(SIG_BLOCK, &sigint_set, NULL);

然后在要循环的线程中轮询SIGINT

sigset_t sigint_set;
siginfo_t info;
const struct timespec zero_timeout =  0, 0 ;

sigemptyset(&sigint_set);
sigaddset(&sigint_set, SIGINT);    

while (sigtimedwait(&sigint_set, &info, &zero_timeout) != SIGINT)

    /* Do something */

【讨论】:

以上是关于虽然没有收到信号?的主要内容,如果未能解决你的问题,请参考以下文章

Qt DBus没有收到信号

Linux信号:孩子没有收到

没有收到来自父进程的信号

暂停执行直到收到套接字上的特定消息?

没有收到 django-paypal IPN 信号

在Java线程的串口调用中没有收到Native SIGIO信号