作者:lUCian_yao 下面是我的理解,不知道對不對。 首先要界定一個范圍(代碼段,函數)然後才可以討論重入。 比如以函數A,B分別為一個范圍。在運行A的時候發生中斷,調用B,B運行完了又返回A,這個時候稱B進入A. 如果A=B,那麼稱A重入A,或者可以說有兩個A的實例在運行。 重入導致的問題主要就是由於這兩個A可以會幾乎同時訪問一些堆中的變量而出現不一致。解決這個問題的辦法有幾個: 干脆不允許某個函數(某段代碼)重入,也就是如果A運行,當發生中斷的時候,調用A,發現已經有A運行了,則返回,不再運行這個新的A.bottom half采用這個辦法。 或者對一些臨界區上鎖。 或者干脆關中斷。 內核的重入,首先界定的范圍就是整個處於內核級的代碼段。 因此,內核的重入可以說是經常發生的,比如中斷發生時。 內核的重入有兩種情況: 1與進程無關的中斷發生時,CPU已經在內核中運行,也就是中斷嵌套。一般內核會做一定的保護,比如關中斷,鎖臨界區等。但是這種中斷有一個特點,就是先進後出的棧的模式,因此,用一個棧足矣。 2與進程相關的切換。如果總是在內核返回到用戶級代碼段時才切換,那麼這個意義上的重入就不存在,用一個內核棧就可以了。還有一種可能是在內核中就切換,由於進程執行並不是按照先進先出的模式,因此,每個進程都有一個內核棧。 還有一個問題,上面與進程無關的中斷一般訪問與進程無關的數據,所以需要保護的數據比較少。在這種重入中,幾個進程的內核實例會訪問與進程相關的共有數據,會導致不一致,而這種臨界區會比較多,所以上鎖可能會比較麻煩,Linux采用的是一種非透明的切換,即當前進程的內核部分必須主動放棄CPU,才可能切換。這樣使內核同步比較簡單。所以Linux內核的重入是一定條件下的重入,非搶占式的重入。 現在有人給Linux打了個補丁,使得它成為搶占式的內核(見新聞版)。也許看了這個補丁,會對內核的重入有一個更深入的認識。