为什么即使SIGUSR1被阻止,epoll_wait而不是sigwait也会捕获SIGUSR1信号

时间:2019-07-12 01:08:47

标签: linux signals epoll

我有一个带有多个线程的C ++程序。在主线程的开始(在生成任何线程之前),我使用sigprocmask阻止SIGUSR1。然后,我创建两个线程,一个使用sigwait等待SIGUSR1,另一个使用epoll_wait监视文件描述符。由于某种原因,当我向该程序发送SIGUSR1时,它会被epoll_wait而不是sigwait捕获。

Linux版本4.9.165

我曾尝试在调用epoll_wait之前显式阻止SIGUSR1,但这不能解决问题。我也尝试过直接使用epoll_pwait。

// main thread

   // ...

   sigset_t sigset;
   sigemptyset(&sigset);
   sigaddset(&sigset, SIGUSR1);
   pthread_sigmask(SIG_SETMASK, &sigset, NULL);

   // ...


//thread 1

   // ...

   sigset_t sigset;
   int sig;
   sigemptyset(&sigset);
   sigaddset(&sigset, SIGUSR1);
   auto ret  = sigwait(&sigset, &sig);

   if (ret != 0)
   {
        std::cout << "sigwait failed\n";
   }

   // ...

//thread 2

    static constexpr int MAX_EVENTS = 10;
    struct epoll_event events[MAX_EVENTS];
    int timeout = -1;

    // ...

    sigset_t oldset;
    sigprocmask(SIG_SETMASK, NULL, &oldset);
    std::cout << (sigismember(&oldset, SIGUSR1) ? "SIGUSR1 blocked " : "SIGUSR1 not blocked ") << "in epoll thread\n";

    epoll_wait(epollFd.Get(), static_cast<struct epoll_event*>(events), MAX_EVENTS, timeout);

    if (nfds < 0)
    {
        std::cout << "Epoll wait failed: " << strerror(errno) << '\n';
    }


    // ...

这给了我输出“ Epoll等待失败:系统调用中断”,并且sigwait线程从不唤醒。

我还看到“ epoll线程中的SIGUSR1被阻止”,表明在epoll_wait之前,SIGUSR1信号已被阻止。

我的理解是,子线程应该继承其父级的信号掩码,应该将epoll_wait视为带有空sigmask的epoll_pwait(因此不能更改信号掩码),并且信号应该转到唯一具有未阻塞信号的线程(即带有sigwait的线程)。我不正确吗?

0 个答案:

没有答案