select與poll的接口說明

在linux驅動中,有時候需要實現非阻塞的read和write操作,但用戶不可能週期地去查詢設備是否可讀或可寫吧,那在驅動中就需要實現poll接口,然後在應用層調用select系統調用。

在驅動中需要實現poll接口,其主要內容爲通過poll_wait(讀等待隊列,wait)、poll_wait(寫等待隊列)將讀、寫等待隊列添加到wait表中。注意:poll_wait()本身並不是阻塞的調用,真正的阻塞是應用層調用select()接口,poll()接口就是添加讀、寫等待隊列,返回POLLIN或POLLOUT的狀態。poll_wait()函數所做的工作是把當前進程添加到
wait 參數指定的等待列表(poll_table)中。通常在接收中斷中根據某個接收條件調用wait_up_interruptible(讀等待隊列),而在發送中斷中根據某個發送條件調用wait_up_interruptible(寫等待隊列)。那麼有人就會問:如果一個線程只操作寫,另一個線程只操作讀,而由於poll()中添加了讀與寫的等待隊列,兩個條件中的一個都會喚醒select()去遍歷監聽的讀、寫文件set。如果接收產生了條件喚醒了select(),那是不是也會喚醒發送的那個線程呢?這就需要靠應用層在調用select()接口時的配置了。詳細的調用如下圖所示:

關於驅動中的poll_wait,它的作用就是把當前進程添加到wait參數指定的等待列表(poll_table)中。需要注意的是這個函數是不會引起阻塞。那如果poll_wait不阻塞,當應用層調用select()系統調用時,真正實現阻塞功能是哪裏實現的呢?其實真正的阻塞是在應用層上的select接口函數中。

 

poll_wait()是用在select系統調用中的. 
一般你的代碼會有一個struct file_operations結構, 
其中fop->poll函數指針指向一個你自己的函數, 
在這個函數裏應該調用poll_wait() 

當用戶調用select系統調用時,select系統調用會 
先調用 
poll_initwait(&table); 
然後調用你的 
fop->poll(); 
從而將current加到某個等待隊列(這裏調用poll_wait()), 
並檢查是否有效 
如果無效就調用 
schedule_timeout(); 
去睡眠. 

事件發生後,schedule_timeout()回來,調用 
fop->poll(); 
檢查到可以運行,就調用 
poll_freewait(&table); 

從而完成select系統調用. 

重要的是fop->poll()裏面要檢查是否就緒, 
如果是,要返回相應標誌 


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