[英]multithreaded epoll server: wake up N threads sleeping on the same epoll fd
我有一個多線程epoll服務器。 我創建了一個epoll fd,然后我將讓X個線程epoll_wait()
休眠狀態,並使用epoll_wait()
等待來自該SAME epoll fd的任何事件。
現在我的問題是:如何喚醒N> 1 && N <X的N個線程?
到現在為止,我一直使用Linux特定的eventfd工具,並且僅使用1個線程就可以很好地工作,但是現在有多個線程在等待SAME epoll fd時出現了問題:
情況1)LT:如果我將我的eventfd添加為“級別觸發”模式,則當我寫入eventfd時, 所有線程都將喚醒,這就是級別觸發模式的工作方式:一旦fd更改狀態,就喚醒所有線程。
N = X
情況2)ET:如果我以“邊緣觸發”模式添加eventfd,則在寫入eventfd時僅喚醒1個線程,這就是邊緣觸發模式的工作方式:在收到來自EAGAIN
之前不再有epollfd事件read(eventfd, ...);
。
N = 1
情況3)我也嘗試過使用自管道技巧,向該管道寫入N次將喚醒N個線程。 相反,它不起作用:它不可靠,有時一個線程從管道中讀取2個“令牌”,有時為1或3。
N =隨機
在所有嘗試的情況下,我無法僅獲得N = N,我無法僅喚醒N個線程,而不能喚醒1個或ALL或RANDOM。 我想念什么? 有什么想法嗎? 注意:我也嘗試了eventfd專用的EFD_SEMAPHORE
標志,而沒有任何幫助。
根據eventfd手冊頁。
如果計數器的值大於0,則文件描述符是可讀的(select(2)readfds參數; poll(2)POLLIN標志)。
通過使用EFD_SEMAPHORE
標志創建一個eventfd:
(如果)eventfd計數器的值非零,則read(2)返回8個字節,其中包含值1,並且該計數器的值減1。
使用帶信號量的( EFD_SEMAPHORE
標志),NONBLOCK( EFD_NONBLOCK
標志)eventfd,然后等待級別觸發的epoll()
或普通poll()
。
使用eventfd_write(fd, N)
編寫要喚醒的N個線程。
當線程喚醒時,您執行read()
。 如果收到EAGAIN
錯誤,則可能會因為進入N次成功讀取而回到睡眠狀態,因此N個線程知道它們必須保持喚醒狀態。
所有線程都喚醒( 雷聲群問題)。
正如您在注釋中所闡明的那樣,由於您將主要退出喚醒線程,因此您可以執行以下操作:
這將喚醒第二個線程,它從管道讀取數字(現在為N-1)。 如果它> 1,則將其遞減並寫入自管道並退出。 ...
以此類推,最后一個線程從管道讀取1。 該線程應退出,但不再寫入管道。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.