【问题标题】:Best practice for waiting for events on multiple threads in Linux (like WaitForMultipleObjects)在 Linux 中等待多线程事件的最佳实践(如 WaitForMultipleObjects)
【发布时间】:2019-08-03 16:53:05
【问题描述】:

在 Windows 中有一个 API WaitForMultipleObjects,如果一个事件在多个线程中注册,它会在事件发生时只唤醒一个线程。我现在必须移植一个在其线程池中使用它的应用程序,并且我正在寻找在 Linux 中执行此操作的最佳实践。

我知道epoll 可以等待 fds(我可以使用 pipe 创建),但是在多个线程中等待一个 FD 可能会在只需要一个时唤醒每个线程。

在 Linux 上实现此行为的最佳做法是什么?我真的不想将一个事件拆分为拥有与工作线程一样多的 FD,因为这可能会在某些系统上达到 FD 限制,因为我有很多事件(所有事件都会被拆分)。

我的想法是创建 1 个主线程,将工作委派给可用的工作人员(如果所有工作人员都在工作,则将任务排队),但这意味着我有一个额外的上下文切换(从而放弃计算时间) 因为主人会醒来,然后唤醒另一个工人。如果没有其他可能干净地实现这一点,我会这样做。不幸的是,我无法摆脱当前的架构,所以我需要解决这个问题。

是否有适用于此类问题的 API?

【问题讨论】:

    标签: linux multithreading pthreads waitformultipleobjects


    【解决方案1】:

    epoll() 是正确的解决方案,尽管您可以考虑使用eventfd() 文件描述符而不是pipe() 文件描述符来发送事件信号。从epoll(7) man page看这篇文字:

    如果多个线程(或进程,如果子进程继承了 epollfork(2) 的文件描述符)被阻止 epoll_wait(2) 等待相同的 epoll 文件描述符 以及兴趣列表中标记为的文件描述符 边缘触发 (EPOLLET) 通知已准备就绪,只是其中之一 线程(或进程)从epoll_wait(2) 唤醒。这提供了 在某些情况下避免“雷声”唤醒的有用优化 场景。

    因此,要获得这种单唤醒行为,您必须在 same epoll 描述符上的每个线程中调用 epoll_wait(),并且您必须在epoll 设置为边沿触发。

    【讨论】:

    • 非常感谢!出于某种原因,我在文档中完全阅读了它!你拯救了我的一天!
    猜你喜欢
    • 2011-10-15
    • 1970-01-01
    • 2013-02-02
    • 1970-01-01
    • 2014-06-04
    • 1970-01-01
    • 1970-01-01
    • 2021-12-14
    • 2014-12-29
    相关资源
    最近更新 更多