虽然没有收到信号?
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 */
【讨论】:
以上是关于虽然没有收到信号?的主要内容,如果未能解决你的问题,请参考以下文章