LDD高級字符驅動程序-poll,epoll,select

1,poll,epoll,select用途基本一樣,經常用在需要操作多個輸入和輸出流而又不阻塞與其中任何一個輸入或輸出流的進程中(關鍵在於多個,如果數量是一個作用體現不是很明顯,如果文件描述符個數爲一個可以使用異步通知操作);

       底層都是通過 int (*poll)(struct file *filp,poll_table *table);函數來實現的,poll函數是作爲struct file_operations 實例對象的成員函數指針poll來調用的;


2,模塊中poll函數的實現由關鍵的兩大步驟來完成,由內核系統調用sys_poll來回調被poll監控的文件描述符對應的模塊中的poll函數(通過struct file_operations 實例對象的成員函數指針分量來調用);

     step 1,調用void poll(struct file *filp,wait_queue_head_t *wait_queue,poll_table *table);函數將用戶空間調用libc庫中poll函數的進程初始化的等待隊列入口項加入等待隊列;如果被監控的文件描述符沒有一個能夠執行無阻塞操作,則在sys_poll系統調用函數中通過count變量綜合評估之後,調用用戶空間poll函數的進程休眠等待,等待在每一個文件描述符對應模塊中的等待隊列上,如果有某一個或多個文件描述符能夠進行無阻塞操作,則喚醒文件描述對應模塊的相應等待隊列上的所有非獨佔進程及一個獨佔進程;調用了用戶空間poll函數的進程(調用了sys_poll系統調用的進程)返回到用戶空間進行彙報一個或多個文件描述符能夠進行無阻塞操作,然後進程進行相應的無阻塞操作;


    step 2,根據是否滿足阻塞條件返回滿足與不滿足相對應的原語掩碼,sys_poll系統調用遍歷回調每一個文件描述符對應的模塊poll函數之後得到這個返回值,最後通過對所有的掩碼和對應文件描述符的請求掩碼進行按位與(&)運算之後,綜合得到能夠進行無阻塞操作的數量count,如果count大於0則poll進程(調用了sys_poll系統調用的進程)不休眠直接返回到用戶空間彙報,如果count小於等於0則poll進程休眠等待,等待在每一個文件描述符對應模塊的等待隊列上;


上述兩部核心關鍵操作,是linux內核源代碼中的關鍵點,這些點通過內核源代碼貫穿在一起;


用戶空間請求和linux內核空間返回的10(11)個原語掩碼如下:

   ·a,讀操作相關的:POLLIN,POLLRDNORM,POLLRDHAND(頻帶讀),POLLPRI(高優先級讀,select函數中解析爲錯誤),

    b,寫操作相關的:POLLOUT,POLLWTNORM,POLLWTHAND,

    c, 錯誤相關的   : POLLERR,POLLHUP(select函數中解析爲讀),POLLINTR.  


3,poll,epoll,select區別於聯繫:  功能相同爲什麼會出現不同形式?這三個函數是操作系統不同時期的不同版本實現,

             a,select 是Unix實現,根據文件描述符對應模塊的阻塞位(O_NONBLOCK)是否設置,可以調用了select函數進程本身實現無阻塞操作;

             b,poll是System V實現,

             c,epoll是linux2.5之後實現,提升了poll的性能,epoll將poll文件描述符數量擴展到上千個(poll函數會將poll_table 數據結構釋放掉,而epoll不會將poll_table(數據結構不太確定?) 數據結構釋放以便重複利用從而提高性能)。


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