C++ C++;任何信号上的轮询错误

C++ C++;任何信号上的轮询错误,c++,signals,polling,C++,Signals,Polling,我的SIGTERM和SIGINT信号处理程序在接收任何一个信号时都会导致轮询错误。我不知道它为什么会这样做,我想我不知道我错过了什么行动 while(!signalHandler.gotExitSignal()) { switch (poll(&ufds[0], NUM_FDS, POLL_TIMEOUT)) { case -1: { throw std::runtime_error("poll error (-1)"); /* ABORT

我的SIGTERM和SIGINT信号处理程序在接收任何一个信号时都会导致轮询错误。我不知道它为什么会这样做,我想我不知道我错过了什么行动

while(!signalHandler.gotExitSignal()) {
    switch (poll(&ufds[0], NUM_FDS, POLL_TIMEOUT)) {
        case -1: {
            throw std::runtime_error("poll error (-1)"); /* ABORT */
        }
        .
        .
我的signalHandler是一个包含sigaction处理的类

struct sigaction killAction, termAction;

memset(&killAction, 0, sizeof(struct sigaction));
killAction.sa_handler = SignalHandler::ExitHandler;
sigemptyset(&killAction.sa_mask);
killAction.sa_flags = 0;
if(sigaction(SIGTERM, &killAction, NULL) < 0)
    throw SignalException("sigaction failed for killAction");

memset(&termAction, 0, sizeof(struct sigaction));
termAction.sa_handler = SignalHandler::ExitHandler;
sigemptyset(&termAction.sa_mask);
termAction.sa_flags = 0;
if(sigaction(SIGTERM, &termAction, NULL) < 0)
    throw SignalException("sigaction failed for termAction");
struct sigaction killAction,termAction;
memset(&killAction,0,sizeof(struct-sigaction));
killAction.sa_handler=SignalHandler::ExitHandler;
sigemptyset(&killAction.sa_mask);
killAction.sa_标志=0;
if(sigation(SIGTERM,&killAction,NULL)<0)
throw SignalException(“killAction的sigaction失败”);
memset(&termAction,0,sizeof(struct-sigaction));
termAction.sa_handler=SignalHandler::ExitHandler;
SIGEPTYSET(和termAction.sa_掩码);
termAction.sa_标志=0;
if(sigaction(SIGTERM,&termAction,NULL)<0)
抛出信号异常(“针对termAction的sigaction失败”);
因此,我给出的代码段循环的预期行为应该是:

  • 而(!signalHandler.gotExitSignal()){
  • 开关(轮询(&ufds[0],NUM\u FDS,轮询超时)){
  • 投票后做一些清理工作
  • 转到1
  • 而(!signalHandler.gotExitSignal()){
  • 打断
  • 开关(轮询(&ufds[0],NUM\u FDS,轮询超时)){
  • 投票后做一些清理工作
  • 转到1
  • 断环
  • 正在发生的事情:

  • 而(!signalHandler.gotExitSignal()){
  • 开关(轮询(&ufds[0],NUM\u FDS,轮询超时)){
  • 投票后做一些清理工作
  • 转到1
  • 而(!signalHandler.gotExitSignal()){
  • 打断
  • 抛出std::runtime_错误(“轮询错误(-1)”

  • 我尝试了一个场景,在轮询切换后,我休眠了2秒钟,然后终止了程序-它以循环条件优雅地退出。问题存在于我轮询然后接收信号时。我不使用SIGHUP信号,它用于通知程序重新加载其配置,但我为SIGHUP设置了一个信号,以进行测试并重新加载像我的其他信号一样,我用轮询错误终止了我的程序。但是我不能让我的程序在任何信号上崩溃,我想知道我是否忘记了什么。这是意料之中的。在poll()中阻塞并且信号到达时,轮询将失败,errno将设置为
    EINTR
    。大多数系统调用都会得到相同的行为

    您可以也应该检测到这一点(现在您也可以更快地跳出轮询循环,因为poll()将返回 当捕捉到信号时。)

    您很可能也想为sigaction设置
    SA_RESTART
    标志

     killAction.sa_flags = SA_RESTART;
    
    这将导致大多数系统调用在捕获信号时不返回错误。有关详细信息,请阅读sigaction()的手册页,并阅读中的“信号处理程序中断系统调用和库函数”部分


    值得注意的是,poll()仍然会被信号中断(立即返回错误),而不管设置
    SA_RESTART
    标志如何。

    这是意料之中的。在poll()中阻塞且信号到达时,poll()将失败,errno将设置为
    EINTR
    。大多数系统调用都会得到相同的行为

    您可以也应该检测到这一点(现在您也可以更快地跳出轮询循环,因为poll()将返回 当捕捉到信号时。)

    您很可能也想为sigaction设置
    SA_RESTART
    标志

     killAction.sa_flags = SA_RESTART;
    
    这将导致大多数系统调用在捕获信号时不返回错误。有关详细信息,请阅读sigaction()的手册页,并阅读中的“信号处理程序中断系统调用和库函数”部分


    值得注意的是,poll()仍然会被信号中断(立即返回错误),而不管是否设置了
    SA_RESTART
    标志。

    因为信号可能中断了被调查fds上的任何操作
    poll()
    应使用-1进行紧急救援(该开关在结果BTW上非常无用)并且errno EINTR.与您的信号处理程序定义无关。因为信号可能中断了被调查的fds上的任何操作
    poll()
    应使用-1进行紧急救援(顺便说一句,该开关在结果上毫无用处)还有,errno EINTR.与你的信号处理器定义无关。多么大量的信息。非常感谢。多么大量的信息。非常感谢。