天天看點

I/O 阻塞&非阻塞&同步&異步

阻塞(blocking)&非阻塞(non-blocking)I/O

阻塞/非阻塞的關注點在與調用者是否等待被調用者傳回。

在實際應用中,大多數I/O請求是阻塞的,這意味着在I/O完成之前,控制權不會回到調用者手中。這種延遲在某些情況下會非常長,比如說執行read()或者write()操作。

而非阻塞I/O 會在發出IO請求後控制權立即轉移到調用者手中,即使資料包沒有準備好,也會傳回一個錯誤辨別,使得操作程序不會阻塞在那裡。

下面的圖很好的解釋了阻塞I/O和非阻塞I/O

I/O 阻塞&非阻塞&同步&異步

圖(a)中,使用者線程送出請求後一直等待直到結果傳回;圖(b)中,使用者線程送出請求後立刻得到了響應,即使I/O操作并沒有完成。随後使用者線程可以進行其他的操作,核心線程執行完成I/O操作後會把結果存放在某個變量中或者是通知使用者線程操作完成。

同步(synchronous)&異步(asynchronous) I/O

同步/異步的關注點在于調用者以什麼樣的形式拿到結果。

如果采用阻塞I/O,由于調用者拿到結果前一直處于等待狀态,因而此時一定是同步的。是以隻有在采用非阻塞I/O時才能更好的區分 I/O的同步/異步。

上面“非阻塞”時已經講過核心程序執行完成I/O操作後會把結果存放在某個變量中或者是通知使用者程序操作完成。如果是存儲在變量中,需要使用者程序使用poll的方式去輪詢拿到結果,此時是同步的;如果核心線程發出觸發信号将結果給使用者線程或者使用者線程以回調的形式拿到結果此時是異步的。

使用圖解的話就是下面的情況:

I/O 阻塞&非阻塞&同步&異步

圖(a)中,使用者線程一直在輪詢結果;圖(b)中,核心線程将結果給使用者線程。

總結

綜上:

(1)阻塞=同步; 同步!=阻塞;

(2)阻塞/非阻塞指的是線程是否一直在等待結果,不能做其他的事情,如果等待是阻塞,否則是非阻塞;

(3)異步=非阻塞;非阻塞 !=異步;

(4)同/異步指的是I/O執行結果是否由調用者去監控并擷取,如果是則是同步,否則是異步。

繼續閱讀