C 当信号未收到时?

C 当信号未收到时?,c,linux,pthreads,signals,posix,C,Linux,Pthreads,Signals,Posix,所以我最近一直在用C编程,研究信号和POSIX线程。我知道我可以在线程中等待一个信号,但我一直在想,是否有可能有一个线程包含一个while循环,该循环将在没有收到SIGINT时永远执行。 所以基本上我不是在等待信号(停止while循环的执行),而是一直执行直到收到信号。只是在听一个特定的信号 我试着用谷歌搜索,但没用 有什么建议吗?提前谢谢 使用一个简单的信号处理器怎么样 #include <stdio.h> #include <stdlib.h> #include &l

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

我试着用谷歌搜索,但没用


有什么建议吗?提前谢谢

使用一个简单的信号处理器怎么样

#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; }
#包括
#包括
#包括
#包括
静态无效信号处理器(int signum);
volatile static int done=0;
int main(int argc,char*argv[])
{
if(信号(SIGINT,SIGINT_处理程序)=SIG_错误){
perror(“信号()”);
出口(1);
}
而(!完成){
(无效)printf(“工作…\n”);
(无效)睡眠(1);
}
(void)printf(“got SIGINT\n”);
返回0;
}
无效信号处理器(信号处理器)
{done=1;}

编辑:使
完成
变得易变,感谢约瑟夫·昆西在评论中指出了这一点。有关相关讨论,请参阅。

您可以阻止该信号,然后使用带有零超时的
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 */
}

正如@xbug所示,虽然等待信号是安全和可预测的,但这并不是最初处理信号的方式。程序可以在启动期间注册几个信号处理程序,并且无论程序处于何种运行状态,只要信号到达,操作系统都会停止程序并直接跳转到相应的处理程序中!在信号处理程序中进行清理并优雅地退出可能有点困难。那么——暂停线程,直到收到信号为止?它避免了繁忙的等待,并且在被中断之前它不会返回(通过某种信号;您要确保SIGINT通过您的线程)?如果您希望线程在等待信号到达时做一些其他工作,那么这不是解决方案,但是如果线程在信号到达之前什么也不做,那么这是等待信号到达的最佳方式。@JonathanLeffler但问题是,线程必须不断生成数据并将其存储到堆中,因此,等待不是一种选择p然后
pause()
不是问题的答案。寄存器信号处理程序可能会失败。需要检查返回值
signal(SIGINT,SIGINT\u handler)
SIG\u ERR
Awesome!!非常感谢你!!!这很好:D但是定义全局变量不是不安全吗?如果有人可以调整该变量,代码将在while循环退出时关闭。有没有更安全的方法来实施这种方法?我不知道你说的“不安全”是什么意思;该变量被声明为
static
,因此该文件之外的任何东西都看不到它(请参见中的案例2)。“某人”必须在进程地址空间内,并且知道链接器甚至没有导出的变量的运行时地址,因此它是非常安全的(简而言之)。