1

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

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

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

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

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

4

1 回答 1

1

epoll()是正确的解决方案,尽管您可以考虑使用eventfd()文件描述符而不是pipe()文件描述符来发送事件信号。epoll(7)请参阅手册页中的此文本:

如果多个线程(或进程,如果子进程继承了epoll文件描述符)在等待同一个文件描述符fork(2)时被阻塞, 并且兴趣列表中标记为边缘触发()通知的文件描述符准备就绪,只需其中一个线程(或进程)从. 这为在某些情况下避免“雷声”唤醒提供了有用的优化。epoll_wait(2)epollEPOLLETepoll_wait(2)

因此,要获得这种单唤醒行为,您必须在同一个epoll_wait()epoll 描述符上调用每个线程,并且您必须在 epoll 集中将事件通知文件描述符注册为边缘触发。

于 2019-08-05T01:33:42.820 回答