在linux系統中,eventfd 是乙個用來通知事件的檔案描述符,timerfd 是定時器事件的檔案描述符。二者都是核心向使用者空間的應用傳送通知的機制,可以有效地被用來實現使用者空間的事件/通知驅動的應用程式。
簡而言之,就是 eventfd 用來觸發事件通知,timerfd 用來觸發將來的事件通知。
當僅用於實現訊號通知的功能時,eventfd() 完全可以替代 pipe(),對於核心來說,eventfd 的開銷更低,消耗的檔案描述符數目更少(eventfd 只占用乙個描述符,而 pipe 則需要兩個)。
eventfd 的兩個核心操作
read()
消費者需要對訊號量進行 down 操作時,呼叫 read 從 eventfd 讀即可。read返回值:
如果當前 counter > 0,那麼 read 返回 counter 值,並重置 counter 為0;
如果當前 counter 等於0,那麼 read 阻塞直到 counter 大於0;如果設定了nonblock,那麼返回-1,並設定 errno 為eagain。
可以看到,eventfd 實現的資源是一次性消耗品,只允許一次 read。
write()
生產者需要執行 up 操作時,呼叫 write 寫乙個 64bit 的整數 value 到 eventfd 即可。write 返回值:
counter 最大能儲存的值是 0xffff ffff ffff fffe(以max表示此值),那麼 write 嘗試將 value 加到 counter上,如果結果超過 max,那麼 write 一直阻塞直到有 read 操作發生,或者返回-1並設定 errno 為 eagain。
所以 write 可以多次連續呼叫,但 read 讀一次即可清零。實質上它應該是乙個二元訊號量,只有0和非0兩種狀態。但是應用程式也可以利用 counter 的值實現自己的邏輯,比如每次 write 都加 1,那麼 read 就能夠知道在兩次呼叫之間有多少次 write 操作發生,也就表示對應的事件發生了多少次。
消費者
消費者執行緒池中的執行緒和生產者共用乙個 epoll 物件,每個消費者執行緒並行地進行針對 eventfd 或 timerfd 觸發的事件迴圈的輪詢。如果是讀事件,且事件 id 為註冊過的 eventfd 或 timerfd,則進行相應的處理。然後執行 eventfd/timerfd 的 read() 操作(相當於 down),並登出執行完的 eventfd 或 timerfd。
建立消費者執行緒池:
class eventpool(object):
def __init__(self, name, num_threads=4):
super(eventpool, self).__init__()
self.name = name
self._epoll = select.epoll()
self._events = {}
for _ in range(num_threads):
w = epollthread(self.name, self._epoll, self._events, self._attach_event)
w.start()
消費者執行緒執行:
def run(self):
while true:
events = self._epoll.poll(1)
for fd, event in events:
if fd in self._events and event & select.epollin:
self._exec_handler(self._events[fd])
self._events[fd]['fd'].read()
self._events.pop(fd)
生產者建立 eventfd/timerfd 並在 epoll 物件中註冊事件,然後執行 eventfd/timerfd 的 write() 操作(相當於 up)。
if expire is not none:
tfd = timerfd()
v = max(1e-3, expire)
self._epoll.register(tfd.get_fd(), select.epollin | select.epollet)
_add_event(tfd, msg)
tfd.set_time(v)
else:
efd = eventfd()
self._epoll.register(efd.get_fd(), select.epollin | select.epollet)
_add_event(efd, msg)
efd.write()
參考
讓事件飛 ——linux eventfd 原理與實踐
worker pool with eventfd
eventfd 函式使用介紹
生產消費者
producer consumer model include include define buffer size 100 緩衝區數量 define max seq 200 define n consumer 10 消費者數量 define n producer 3 生產者數量 define t ...
生產者消費者 生產者與消費者模式
一 什麼是生產者與消費者模式 其實生產者與消費者模式就是乙個多執行緒併發協作的模式,在這個模式中呢,一部分執行緒被用於去生產資料,另一部分執行緒去處理資料,於是便有了形象的生產者與消費者了。而為了更好的優化生產者與消費者的關係,便設立乙個緩衝區,也就相當於乙個資料倉儲,當生產者生產資料時鎖住倉庫,不...
生成者消費者問題
自己實踐的 生成者消費者問題 public class threaddemo 生產者 class producer implements runnable public void run 消費者 class consumer implements runnable public void run c...