epoll機制總結

看了一週的linux epoll源代碼做一個總結。

epoll源代碼在eventpoll.c裏。首先是調用epoll_create,內部調用sys_epoll_create,這個函數主要給epoll分配文件描述符fd和文件結構體struct file,並實現file、fd、epoll私有數據結構eventpoll的綁定,主要的函數是ep_alloc和anon_inode_getfd,ep_alloc初始化eventpoll結構體的各種隊列和epoll的紅黑樹,這個紅黑樹用來ll_ctl內部調用sys_epoll_ctl,首先根據epoll文件描述符的參數獲取struct file,然後這個函數最複雜最重要的部分是ep_insert,這個函數參數分別是eventpoll結構體,要添加的事件event,要添加的文件描述符和對應的file結構體。首先分配epitem內存並初始化它的各種隊列。有幾個比較重要的函數init_poll_funcptr(&epq.pt, ep_ptable_queue_proc);revents = tfile->f_op->poll(tfile, &epq.pt);前一個函數是向epq.pt綁定一個回調函數,後一個函數是直接調用待添加文件的poll函數,在poll函數內部會回調epq.pt即ep_ptable_queue_proc。ep_ptable_queue_proc函數有如下幾個參數:目標文件的file,目標文件的等待隊列和這個函數本身的函數指針,新建一個wait_queue_t進行相關賦值設置回調函數最後把這個結構體插入到目標文件的等待隊列。當網絡有事件到來有數據(收到數據會出發以下函數tcp_v4_rcv->......->wake_up_interruptible_all->最後wake_up_all)會回調等待隊列的回調函數,回調函數會把這個epitem插入到eventpoll的已完成隊列中並喚醒epoll_wait。epoll_wait內部調用sys_epoll_wait,內部調用ep_poll。首先判斷eventpoll結構體的已完成等待隊列是否有已經完成的任務,如果就創建一個wait_queue存放當前進程得信息和回調函數並加入到eventpoll的wq隊列中,如果所要監聽的有數據就回調ep_ptable_queue_proc函數中已經註冊的函數,這個函數內部回調eventpoll的wq隊列的回調函數進而喚醒epoll_wait判斷來的事件是不是所要監聽的事件如果是就把這個事件通過ep_send_events函數拷貝到用戶空間並返回。

接下來說下epoll內部常用的幾個隊列。epoll的eventpoll結構體最重要的一個隊列是rdllist,這個隊列指向有消息的隊列,ep->wq被epoll_wait等候的隊列ep->rb,紅黑樹用於保存epitem,紅黑樹可以加快查找速度,ep->rb根據被檢測目標文件epitem的struct file和fd來進行紅黑樹比較插入,當有事件發生時,epi->rdllink被插入到ep->rdllist,當有事件到來時候,會把epoll_wait阻塞的進程進行喚醒,根據rdllist裏面的結構體找到對應的epitem,根據對應的epitem找到被監控文件的file並執行poll再一次確認得到消息event

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章