ppoll 中的信号未立即处理

Posted

技术标签:

【中文标题】ppoll 中的信号未立即处理【英文标题】:Signals in ppoll not handled immediately 【发布时间】:2017-02-15 15:37:37 【问题描述】:

我写了一个小的 ppoll 测试,但我对信号处理感到困惑。手册页说:

poll() 和 ppoll() 之间的关系类似于 select(2) 和 pselect(2) 之间的关系:和 pselect(2) 一样,ppoll() 允许应用程序安全地等待,直到文件描述符变为准备好或直到捕获到信号。

在我的情况下,fd 更改会立即处理,而信号会在超时后处理。我在进程上下文中使用了 ctr-c 并从另一个 shell 中终止,但始终是相同的行为。

我做错了什么?我错过了什么吗?

#include <iostream>
#include <poll.h>
#include <signal.h>
#include <unistd.h>

void handleSignal(int signal)

    switch(signal)
    
        case SIGINT:
            std::cerr << "sigint" << std::endl;
            break;
        case SIGTERM:
            std::cerr << "sigterm" << std::endl;
            break;
        default:
            std::cerr << "sig=" << signal << std::endl;
            break;
    


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

    int result;
    FILE *fd = fopen("/tmp/tmpFile", "r");
    result = fileno(fd);
    if(-1 == result)
    
        std::cerr << "could not open temp file"  << std::endl;
        return EXIT_FAILURE;
    

    pollfd fds[2];
    fds[0] =  0, POLLIN, 0 ;
    fds[1] = result, POLLIN, 0 ;

    sigset_t mySigset, oldSigset;
    sigemptyset(&mySigset);
    sigaddset(&mySigset, SIGINT);
    sigaddset(&mySigset, SIGTERM);

    struct sigaction mySigHandler;
    mySigHandler.sa_handler = &handleSignal;
    mySigHandler.sa_flags = 0;
    sigemptyset(&mySigHandler.sa_mask);
    sigaction(SIGINT, &mySigHandler, NULL);
    sigaction(SIGTERM, &mySigHandler, NULL);

    char buffer[1024];
    timespec time;
    while(true)
    
        time = 20, 0;
        result = ppoll(&fds[0], 2, &time, &mySigset);
        if(0 == result)
        
            // timeout
            std::cout << "ppoll timeout" << std::endl;
        
        else if(0 > result)
        
            // error
            std::cerr << "ppoll error" << std::endl;
        
        else
        
            // at least one fd changed
            std::cout << "active fds: " << result << std::endl;

            for(int i = 0; i < 2; i++)
            
                if(fds[i].revents & POLLIN)
                
                    result = read(fds[i].fd, buffer, 1024);
                    if (-1 == result)
                    
                        std::cerr << "error while reading fd " << fds[i].fd << std::endl;
                    
                    else if(0 < result)
                    
                        buffer[result] = '\0';
                        std::cout << "read fd " << fds[i].fd << ": " << buffer << std::endl;
                    
                
            
        
    
    return EXIT_SUCCESS;

【问题讨论】:

【参考方案1】:

当您调用ppoll 时,您告诉它通过在信号掩码中传递SIGINTSIGTERM 来阻止它们。

【讨论】:

非常感谢。我阅读了太多手册页,无法自己解决这个问题。有道理,否则我本可以使用 poll 函数。

以上是关于ppoll 中的信号未立即处理的主要内容,如果未能解决你的问题,请参考以下文章

Qt 对象信号未连接到方法(处理程序)

linux 信号处理

solaris 上的 ppoll

PySide 中未处理的信号

Signal处理中的函数可重入问题

Android - JNI / NDK - 与SIGSEV崩溃 - 未触发信号处理