管道+选择:选择永不醒来

时间:2016-07-08 12:02:06

标签: c++ multithreading select pipe

我正在构建一个小的io服务来检查某些fds的读写可用性。

为此,我有一个专门用于选择的线程,没有任何超时,因此只有当fd可用时才会唤醒选择。

但是,我有时希望强制选择在特定事件中被唤醒。为此,我只需使用管道,监视其读取可用性,并在我想要唤醒选择呼叫时写入。

这大部分时间都有效,但有时我写入管道时没有任何反应。因此,选择呼叫将无限期地被阻止。

以下是我使用的代码的一部分:

选择主题:

FD_ZERO(&rd_set);
//! set some other fds...
FD_SET(m_notif_pipe_fds[0], &rd_set);
select(max_fd + 1, &rd_set, &wr_set, nullptr, nullptr);
if (FD_ISSET(m_notif_pipe_fds[0], &rd_set)) {
  char buf[1024];
  read(m_notif_pipe_fds[0], buf, 1024);
}

通知主题:

write(m_notif_pipe_fds[1], "a", 1);

max_fd变量实际上已设置为最高fd值(不是要监视的fd数,这是一个常见错误)。

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

我建议你让你的管道无阻塞

int flags = fcntl(m_notif_pipe_fd[1], F_GETFL, 0);
assert(flags != -1);    
fcntl(m_notif_pipe_fd[1], F_SETFL, flags | O_NONBLOCK);

并将管道缓冲区大小设置为1

int pipe_sz = fcntl(m_notif_pipe_fd[1], F_SETPIPE_SZ, 1);

请参阅this question