gpt4 book ai didi

linux - 多线程 epoll 服务器 : wake up N threads sleeping on the same epoll fd

转载 作者:太空宇宙 更新时间:2023-11-04 10:56:51 51 4
gpt4 key购买 nike

我有一个多线程 epoll 服务器。我创建了一个 epoll fd,然后我将让 X 个线程休眠,等待 epoll_wait() 来自 SAME epoll fd 的任何事件。

现在我的问题是:如何唤醒 N 个线程,其中 N > 1 && N < X?

直到现在,我一直在使用 Linux 特定的 eventfd 工具,它只在 1 个线程上工作得很好,但现在有多个线程在等待 SAME epoll fd,出现了一个问题:

情况 1) LT:如果我将我的 eventfd 添加为“级别触发”模式,所有 线程将在我写入 eventfd 时唤醒,这就是级别触发模式的工作原理:一次fd 改变状态让我们唤醒所有线程。

N = X

情况 2) ET:如果我将我的 eventfd 添加为“边缘触发”模式,当我写入 eventfd 时,只有 1 线程将被唤醒,这就是边缘触发模式的工作原理: 在我从 read(eventfd, ...); 收到 EAGAIN 之前,不再有 epollfd 事件。

N = 1

案例 3)我也尝试过使用自管道技巧,向管道写入 N 次会唤醒 N 个线程。相反,它不会工作:它不可靠,有时一个线程从管道读取 2 个“ token ”,有时是 1 个或 3 个。

N = 随机

在我尝试过的所有情况下,我不能只得到 N=N,我不能只唤醒 N 个线程,而是 1 或 ALL,或 RANDOM。我错过了什么?有什么想法吗?注意:我还尝试了特定于 eventfd 的 EFD_SEMAPHORE 标志,没有任何帮助。

最佳答案

根据 eventfd手册页。


The file descriptor is readable (the select(2) readfds argument; the poll(2) POLLIN flag) if the counter has a value greater than 0.

通过创建带有 EFD_SEMAPHORE 标志的 eventfd:

(if) the eventfd counter has a nonzero value, then a read(2) returns 8 bytes containing the value 1, and the counter's value is decremented by 1.


使用信号量(EFD_SEMAPHORE 标志),NONBLOCK(EFD_NONBLOCK 标志)eventfd 并等待级别触发的 epoll(),或普通的 poll()

使用 eventfd_write(fd, N) 编写 N 个线程你想醒来。

当线程唤醒时,您将执行 read()。如果你得到 EAGAIN 错误,你可以回去 sleep 因为 N 次成功的读取已经完成并且因此 N 个线程知道它们必须保持清醒。

缺点

所有线程唤醒(thundering herd 问题)。

关于linux - 多线程 epoll 服务器 : wake up N threads sleeping on the same epoll fd,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28540910/

51 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com