linux - 在 Linux 中等待多线程事件的最佳实践(如 WaitForMultipleObjects)

标签 linux multithreading pthreads waitformultipleobjects

在 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 across fork(2)) are blocked in epoll_wait(2) waiting on the same the same epoll 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 from epoll_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/

相关文章:

linux - 按小时计算行数

java - 嵌套同步块(synchronized block)的缺点

c++ - Qt - 在其他线程上运行函数

c - 线程访问静态变量导致段错误

C++正确使用互斥锁

c - Linux 服务器 C 代码在收到信号后停止

linux - Cron 作业命令每 8 小时删除一次文件夹的子文件夹

c++ - "Serial transmit complete"- 中断 RS485 [BeagleBoneBlack - 埃]

python - 如何使用装饰器和线程返回函数值

c++ - Pthread_create() 不正确的启动例程参数传递