Почему сигнал SIGUSR1 перехватывается epoll_wait вместо sigwait, хотя SIGUSR1 заблокирован - PullRequest
0 голосов
/ 12 июля 2019

У меня есть программа на C ++ с несколькими потоками. В начале основного потока (до того, как появятся какие-либо потоки) я блокирую SIGUSR1 с помощью sigprocmask. Затем я создаю два потока, один ждет SIGUSR1 с помощью sigwait, а другой отслеживает дескрипторы файлов с помощью epoll_wait. По какой-то причине, когда я посылаю SIGUSR1 в эту программу, он перехватывается epoll_wait, а не sigwait.

Версия Linux 4.9.165

Я пытался явно заблокировать SIGUSR1 перед вызовом epoll_wait, но это не решает проблему. Я также пытался использовать 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 никогда не просыпается.

Я также вижу «SIGUSR1 заблокирован в потоке epoll», указывающий, что перед epoll_wait сигнал SIGUSR1 был заблокирован.

Насколько я понимаю, дочерние потоки должны наследовать маски сигналов своих родителей, что epoll_wait следует рассматривать как epoll_pwait с нулевой сигма-маской (и, следовательно, не изменять маску сигнала), и что сигнал должен передаваться только поток с разблокированным сигналом (являющийся тем, у которого есть сигвейт). Я не прав?

...