c++ - ppoll 中的信号未立即处理

标签 c++ linux signals

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

The relationship between poll() and ppoll() is analogous to the relationship between select(2) and pselect(2): like pselect(2), ppoll() allows an application to safely wait until either a file descriptor becomes ready or until a signal is caught.

在我的例子中,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;
}

最佳答案

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

关于c++ - ppoll 中的信号未立即处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42253708/

相关文章:

c++ - 如何最好地告诉 CMake 在哪里可以找到 dll

c++ - 错误 : packagename-0. 1-r0 do_compile:函数失败:do_compile

signals - 如何处理或检测 D 中的系统信号?

c++ - 如何根据排序索引 vector 对 std::set 索引进行排序?

javascript - emscripten:如何解决 UnboundTypeError

linux - 我可以在 Ubuntu 上使用 Homebrew 吗?

c - 在 Linux 上使用 gcc 链接共享库

linux - 显示或重定向 shell 的作业控制消息

c - 信号不会在 execv() 中正确重新启用

c++ - Doxygen:如何记录没有#defined 的宏?