應用層對裝置檔案的讀寫,常常會用到輪詢操作。所謂輪詢,就是指的是在讀寫時,若暫時無法讀寫,則卡在那裡,直到可以讀寫。
在應用層,輪詢主要分為三種實現
這種方法的本質是:若讀寫條件不滿足時,則讓程序休眠,直到滿足條件後由其他程序喚醒(一般是外界觸發中斷,因為硬體資源獲得的同時往往伴隨著乙個中斷),然後進行讀寫。其實阻塞io的實現有一點非同步通知的思想
fd = open("/dev/***", o_rdwr);
...ret = read(fd,&buf,1); /*阻塞式(block)讀取*/
wait_queue_head_t read_waitq;
而初始化一般放在驅動的open/probe函式中,如果沒有open/probe的話可以放在module init 的函式中
init_waitqueue_head(read_waitq);
static ssize_t ***_read(struct file *file, const
char *buffer, size_t count, loff_t *ppos)
__set_current_state(task_interruptible);/*標記當前程序為睡眠*/
schedule(); /*交出處理器,排程其他程序*/
if (signal_pending(current))
}}while (rd_flag == 0);
/*讀裝置*/
device_read(...);
rd_flag == 0;/*設定狀態為不可讀*/
out:
remove_wait_queue(&read_waitq, &wait);/* 將節點(當前程序)移出等待佇列 */
set_current_state(task_running);/*標記程序狀態為 task_running*/
return ret;
}
對於驅動,最重要的是普適性,所以讀寫函式中要將阻塞、非阻塞功能都實現。首先上來先判斷能否讀寫,如果不能的話再判斷flag,是否是阻塞訪問,如果是flag是非阻塞,則直接返回-eagain。對於阻塞訪問,會進行狀態切換並通過schedule()排程其他程序執行;至此開始等待其他程序喚醒,醒來的時候要注意,喚醒程序的有可能是訊號,因此,我們首先通過signal_pending(current)
了解是不是訊號喚醒的,是的話立即返回- erestartsys
static irqreturn_t ***_irq(int irq, void *dev_id)
這個方法的本質是:不停地用乙個迴圈,來判斷是否有讀寫的條件,一旦條件滿足就進行非阻塞式讀寫
fd = open("/dev/***", o_rdwr| o_nonblock);
...while(read(fd,&buf,1)!=1)/*判斷是否讀成功*/
/*直到讀成功才跳出迴圈*/
應用層還可以使用系統定義的輪詢介面,poll或select,它們的本質其實都呼叫了驅動中的poll函式。這些介面主要作查詢、監聽的作用,真正的讀寫還是要靠讀寫函式
int
select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
fd_set rfds; /* 分別定義讀寫檔案描述符集合*/
fd = open("/dev/***", o_rdonly | o_nonblock);
/*清除(初始化)讀寫檔案描述符集合*/
fd_zero(&rfds);
/*將當前開啟檔案的fd加入檔案描述符集合*/
fd_set(fd, &rfds);
/*開始查詢*/
select(fd + 1, &rfds, null, null, null);
ret = read(fd, &buf, 1);
}
static
unsigned
int ***_poll(struct file *filp, poll_table *wait)
Linux核心開發之阻塞非阻塞IO 輪詢操作
小王,來聊聊,今天面試的情況怎麼樣,應該挺順利的吧.看著小王平淡的眉頭,我問道。唉,別提了,你說,我的運氣咋這差呢,面試前你不是給我講了有關阻塞的問題嗎,我見了面試官是吧,還跟他好好的用今天排隊的例子說了有關阻塞的問題,但是.小王哀聲嘆氣地說到。別但是了,怎麼啦.可問題是面試官壓根就沒打算問我有關阻...
阻塞I O,非阻塞I O
拿 socket舉例。當read資料時,如果這時沒有資料可讀,阻塞i o會一直等待有資料讀,資料從kernel copy 到socket的buffer後返回 非阻塞i o會立即返回,但如果有資料可讀,非阻塞i o也是等資料從kernel copy 到socket的buffer後返回。以上是阻塞與非阻...
非阻塞IO和阻塞IO
非阻塞io和阻塞io 在網路程式設計中對於乙個網路控制代碼會遇到阻塞io 和非阻塞io 的概念,這裡對於這兩種socket 先做一下說明 基本概念 阻塞io socket 的阻塞模式意味著必須要做完io 操作 包括錯誤 才會返回。非阻塞io 非阻塞模式下無論操作是否完成都會立刻返回,需要通過其他方式...