我有一个带有多个线程的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的线程)。我不正确吗?