close()后的一个线程中的epoll_wait()

时间:2015-09-21 09:40:12

标签: c++ linux multithreading

我有一个主线程和一个工作线程。工作线程的代码如下所示:

thread = ::std::thread([this]() {
    struct epoll_event events[50];

    for (;;)
    {
      if (int const n =
        epoll_wait(efd, events, 50, -1))
      {
      //...

我希望主线程中的close(efd)会导致工作线程的epoll_wait()调用返回,但它不会发生。我该怎么做才能退出工作线程的无限循环?

4 个答案:

答案 0 :(得分:2)

最简单的解决方案可能如下:

  1. 让工作线程包含epoll集中管道的读取端。

  2. 如果epoll_wait表示管道可读,则将工作线程编码为终止。

  3. 要终止工作线程,请将一个字节写入管道的写入端。

  4. 让工作线程关闭epoll套接字,或在加入worker后关闭它。

答案 1 :(得分:2)

我只是遇到了同样的问题,在进行了一些测试之后,这对我有用:

我有一个线程在epoll_wait服务并等待,有一个线程关闭了连接。 结束线程类似于:

shutdown(server_fd, SHUT_RDWR);
close(server_fd);

并且服务器线程无限期挂起(除非服务器线程是主线程)。因此,我将问题隔离开来进行试验并试图更好地理解它,发现删除关闭行并仅关闭server_fd而不关闭它就可以了。

答案 2 :(得分:1)

你最好的选择是从主线程到epoll工作线程使用显式信号(我的意思是,通常意义上的信号;不一定是POSIX信号)。

尝试使用管道的技术是真实的,但有更好的选择:查看eventfd。要使用它,您将创建一个eventfd文件描述符并将其添加到epoll集。通过写入一个8字节的值(值为1就可以)从主线程发出信号。

当工作线程在eventfd上看到一个事件时,它知道它已经发出信号并且应该采取相应的行动。

使用管道的主要优点是它只需要一个文件描述符,并且您不必担心在写入管道时可能会阻塞。

答案 3 :(得分:0)

所以,很长一段时间后,我回答了我自己的问题。就像我在评论中指出的那样,也可以向包含<div ng-repeat="columnConfig in notSorted(data.feature.featureAttributes) | filter : '!stratusid'" ng-if="data.feature[columnConfig].value != '' && data.feature[columnConfig].value != 'F'";> <pb-info-column [columnConfig]=columnConfig [feature]="data.feature" class="multilabelrow col-xs-12 default-topbtm-padding"> </pb-info-column> </div> <div> <pb-info-column [columnConfig]="LotplanConfig" [feature]="data.feature" class="multilabelrow col-xs-12 default-topbtm-padding"> </pb-info-column> <div> 的线程发送信号。

epoll_wait()

当您想杀死等待的线程时:

bool terminate_meh{};

extern "C"
{

static void sig_handler(int) noexcept
{
  terminate_meh = true;
}

}

{
  struct sigaction act{};

  act.sa_handler = sig_handler;
  sigemptyset(&act.sa_mask);

  sigaction(SIGUSR2, &act, {});
}

任何阻止功能(pthread_kill(thread.native_handle(), SIGUSR2); )将被中断,并且epoll_wait()将被设置。