4

在計算的同步/阻塞模型中,我們通常會說等待IO任務完成時,一個執行線程將等待(等待阻塞)。在IO上等待的線程是否也會阻塞內核?

我的問題是,這通常會導致執行線程的CPU內核處於空閒狀態,或者等待IO的線程通常會被上下文切換出來並進入等待狀態,直到IO準備好被處理?

+0

@瑞恩,我猜你可能會有很多關於這個主題的論文,但我只是對可能和通常會發生什麼的一般理解。 – JamieP

+0

我不需要一個資格只是一個普通的駕駛;) – JamieP

+0

對不起,我誤解了。 –

回答

12

CPU內核通常不專用於某個特定的執行線程。內核一直在切換執行進出CPU的進程。 CPU當前正在執行的進程處於「運行」狀態。等待輪到的進程列表處於「準備就緒」狀態。內核非常快速地切換這些進出。現代CPU特性(多核,同時多線程等)嘗試增加一次可以實際執行的執行線程數。

如果一個進程被I/O阻塞,內核會將它放在一邊(置於「等待」狀態),甚至不考慮在CPU中給它一些時間。當I/O完成時,內核將被阻止的進程從「等待」狀態移動到「就緒」狀態,以便它可以在CPU中輪流(「運行」)。

因此,您阻止的執行線程只會阻止:執行的線程。 CPU和CPU內核繼續有其他執行線程切入和切出,並且不會閒置。

+0

@RyanVincent:用戶空間進程可以直接使用內存,而無需進行系統調用。 [等待緩存未命中的進程仍然佔用一個CPU內核](http://stackoverflow.com/questions/19980070/which-one-will-workloadusage-of-the-cpu-core-if-there-is-一個永久緩存-MI)。如果使用繁忙等待螺旋鎖進行線程同步,則也是如此。在等待其他任何事情時,內核會收到通知。它會喚醒正在等待該磁盤塊或網絡數據包的線程。 –

+0

另外,Linux上低prio任務總是會得到一些CPU。最小值prio不是「只有當CPU處於空閒狀態時」,才能避免死鎖,如果低級prio進程佔用資源或其他東西。顯然支持真正的空閒優先級會使調度程序更加複雜,因爲它必須檢查何時完全停止進程是安全的。所以即使不使用它,這也會稍微放慢調度速度,因此Linux不包含它。所以每一個沒有等待的過程都會收到一些時間片。 –

+0

@PeterCordes,感謝您的解釋 - 它有幫助。 –

0

對於大多數以標準方式使用的編程語言,答案是它會阻塞你的線程,但不會阻塞你的CPU。

您需要爲1個線程的特定線程(親和性)明確預留一個CPU來阻塞整個CPU。爲了更加明確,請參閱本question

你可以把SetProcessAffinityMask上的每個過程,但你用排除只是將「屬於」你的過程中,核心口罩,並用它在你的程序設置它只在這個核心上運行(或者,甚至更好,只是在執行時間關鍵任務的線程上運行SetThreadAffinityMask)。

+0

親和力與此相反:它將一個線程標記爲只能在有限的CPU上運行。它*不會停止使用該CPU的其他任務。最近有一個關於如何爲最近的流程預留核心的問題,但我找不到它。 –

+0

您可以使用關聯來排除運行線程的核心上運行的其他進程。 – DevShark