在 Windows 中有一个 API WaitForMultipleObjects
,如果一个事件在多个线程中注册,它会在事件发生时只唤醒一个线程。我现在必须移植一个在其线程池中使用它的应用程序,我正在寻找在 Linux 中执行此操作的最佳实践。
我知道 epoll
可以等待 fds(我可以用 pipe
创建),但是在多个线程中等待一个 FD 可能会唤醒每个线程的事件当只需要一个时。
在 Linux 上实现此行为的最佳实践是什么?我真的不想将一个事件拆分为具有与工作线程一样多的 FD,因为这可能会在某些系统上达到 FD 限制,因为我有很多事件(所有事件都会被拆分)。
我想的是创建 1 个主线程,将工作委托(delegate)给一个可用的工作线程(或者如果所有工作线程都在工作,则将任务排队),但这意味着我有一个额外的上下文切换(因此放弃了计算时间) 因为主人会醒来,然后唤醒另一个 worker 。如果没有其他可能干净地实现它,我会这样做。不幸的是,我无法摆脱当前的架构,所以我需要解决这个问题。
是否有适用于此类问题的 API?
最佳答案
epoll()
是正确的解决方案,尽管您可以考虑使用 eventfd()
文件描述符而不是 pipe()
文件描述符事件信号。从 epoll(7)
man page 中查看此文本:
If multiple threads (or processes, if child processes have inherited the
epoll
file descriptor acrossfork(2)
) are blocked inepoll_wait(2)
waiting on the same the sameepoll
file descriptor and a file descriptor in the interest list that is marked for edge-triggered (EPOLLET
) notification becomes ready, just one of the threads (or processes) is awoken fromepoll_wait(2)
. This provides a useful optimization for avoiding "thundering herd" wake-ups in some scenarios.
因此,为了获得这种单次唤醒行为,您必须在每个线程中使用 相同 epoll 描述符调用 epoll_wait()
,并且您必须注册您的epoll 中的事件通知文件描述符设置为边缘触发。
关于linux - 在 Linux 中等待多线程事件的最佳实践(如 WaitForMultipleObjects),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57340371/