Linux 驅動程式的 I/O, #4: 什麼是 Blocking I/O

jollen 發表於 August 4, 2008 8:13 AM

在先前的專欄中,我們為大家介紹了「I/O」以及「interrupt handling」,接下來我們要將這二個部份合在一起,並討論幾個相當重要的觀念以及機制。首先,我們回到最早在介紹 Linux 驅動程式架構的部份,我們介紹到了 system call 以及 file operations 的觀念;接續 I/O 的部份,我們又提到 read/write system call。到這裡,我們就要融合貫通先前所介紹的重要觀念。請大家先將先前的專欄讀熟,再接續本系列專欄。

在 Linux 驅動程式的整個框架中,最重要,而且必須一開始就先了解的主題有二個:

1. Blocking I/O 的觀念。
2. Wait queue 以及 event-driven(event-polling)的觀念。

雖然這裡分成二個小主題,不過其實這是同樣的一個主題。這裡有很多值得提出討論的觀念,首先針對 Blocking I/O 的觀念進行深度探討。

什麼是 blocking I/O?

當 user process 透過 read/write system call 讀取硬體資料時,會有哪些情況出現?請注意,這裡講的是「user process」,並不是驅動程式的 system call 實作(driver function、fops->read 或 fops->write)。以 user process 呼叫 read() 來讀取硬體資料的案例來說,當然免不了就是以下的情況:

1. 驅動程式能順利由硬體拿到資料,並丟到 user-space 給「該」process。
2. 驅動程式目前無法由硬體拿到資料。怎麼辦?

現在沒辦法馬上由硬體拿到資料,怎麼辦呢?當然要等待了。驅動程式必須設法等到可以由硬體拿到資料為止,再將資料丟給該 process。試想,現在有一個 process 想要讀取硬體資料,第一次的 read() 很順利地馬上就拿到資料了,可是第二次的 read() 因為硬體的關係,驅動程式暫時無法由硬體取得資料,於是 process 的第二次 read() 並不會立刻結束。

Process 這個時候「停在」第二次的 read() 呼叫,但其實此時,系統的執行位置是來到驅動程式的 read driver function(fops->read),而 fops->read 在待候硬體資料。「Blocking」就是「停住」的意思,所以第二次的 read() 動作就變成是 blocking I/O。請注意:

1. 這裡一定是討論 user process 是否會停在 read() 或 write()。Blocking I/O 一定要由 user process 的角度討論才會是正確的觀念。
2. 第二次的 read 是 blocking I/O(blocking operaton),這是「驅動程式的 fops->read 實作」所導致的結果。所以,user process 的 read/write 會不會停住,完全是看 fops->read 與 fops->write 的實作。
3. 我們在這裡只討論驅動程式的 read/write 實作,也就是 user process 存取 device file。

這就是所謂的 blocking I/O。由驅動程式的角度來看,可以總結如下:

1. 當驅動程式想讓 user process 在呼叫 read() 函數時,都保證能取得資料,此時驅動程式便要實作「當目前尚無資料可回傳給 user process 時,便讓 user process 停留等待」的機制(可能是驅動程式尚無法由裝置取得資料)。

2. w當驅動程式想讓 user process 在呼叫 write() 函數時,都保證能寫入資料,此時驅動程式便要實作「當目前無法寫入資料至裝置時,便讓 user process 停留等待」的機制(可能是裝置尚未 ready)。

讓 user process 停止的方式,涉及排程的觀念,這部份在下一篇日記會接著說明。

Also See

Jollen's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue

您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw