阻塞操做是指在執行設備操做時若不能得到資源則掛起進程,直到知足可操做的條件後再進行操做。異步
由於阻塞的進程會進入休眠狀態,所以,必須確保有一個地方可以喚醒休眠的進程。喚醒進程的地方最大可能發生在中斷裏面,由於硬件資源得到的同時每每伴隨着一箇中斷。spa
注意:驅動程序須要提供阻塞(等待隊列,中斷)和非阻塞方式(輪詢,異步通知)訪問設備。orm
休眠(被阻塞)的進程處於一個特殊的不可執行狀態。這點很是重要,不然,沒有這種特殊狀態的話,調度程序就可能選出一個本不肯意被執行的進程,更糟糕的是,休眠就必須以輪詢的方式實現了。進程休眠有各類緣由,但確定都是爲了等待一些事件。事件多是一段時間、從文件I/O讀更多數據,或者是某個硬件事件。一個進程還有可能在嘗試得到一個已經佔用的內核信號量時被迫進入休眠。休眠的一個常見緣由就是文件I/O -- 如進程對一個文件執行了read()操做,而這須要從磁盤裏讀取。還有,進程在獲取鍵盤輸入的時候也須要等待。不管哪一種狀況,內核的操做都相同:進程把它本身標記成休眠狀態,把本身從可執行隊列移出,放入等待隊列,而後調用schedule()選擇和執行一個其餘進程。喚醒的進程恰好相反:進程被設置爲可執行狀態,而後再從等待隊列中移到可執行隊列。隊列
休眠有兩種相關的進程狀態:TASK_INTERRUPTIBLE and TASK_UNINTERRUPTIBLE。它們的唯一區別是處於TASK_UNINTERRUPTIBLE狀態的進程會忽略信號,而處於TASK_INTERRUPTIBLE狀態的進程若是收到信號會被喚醒並處理信號(而後再次進入等待睡眠狀態)。兩種狀態的進程位於同一個等待隊列上,等待某些事件,不可以運行。進程
休眠經過等待隊列進行處理。等待隊列是由等待某些事件發生的進程組成的簡單鏈表。內核用wake_queue_head_t來表明等待隊列。等待隊列能夠經過DECLARE_WAITQUEUE()靜態建立,也能夠有init_waitqueue_head()動態建立。進程把本身放入等待隊列中並設置成不可執行狀態。等與等待隊列相關的事件發生的時候,隊列上的進程會被喚醒。爲了不產生競爭條件,休眠和喚醒的實現不能有紕漏。事件