[英]How are user-level threads scheduled/created, and how are kernel level threads created?
[英]concurrency in user-level and kernel-level threads. why are the outputs different?
我開始學習有關線程的知識,現在到了使本書將我與用戶級線程和內核級線程混淆的時候。
這本書着重強調了差異,並提出了一個問題,說以下兩個相似代碼的輸出是不同的,但是,據我所知,它們的輸出在我看來是相同的。
第一個是關於用戶級線程的:
int number = 0;
int main() {
fork()
if it is child {number--, return 0}
if it is parent {number++, wait till child return, print number}}
我的分析是,由於number--和number ++只必須執行一次,並且在這兩次執行之后輸出將被打印出來,因此輸出必須為0。
第二種情況是關於內核級線程的:
int number = 0;
t1() {number--}
t2() {number++}
main() {
createThread(pass t1)
createThread(pass t2)
wait till both complete
print number
}
在這種情況下,同一件事,內核創建兩個線程,一個-另一個++,因此它們都必須只執行一次。 並且結果必須再次為0。
但是,這本書說輸出是不同的,或者由於干預可能會有不同的輸出,有人可以告訴我為什么嗎?
在第一種情況下,它不是創建線程,而是派生一個進程(查找fork()函數的描述)。 分叉的進程具有其自己的內存,該內存是從父進程復制的,因此子進程中數字減一的結果將不會對父進程產生影響。 父流程中打印號碼的結果將為1。
即使您編寫了一條i++
或i--
指令,也可能會用機器語言將其翻譯成多個指令。 如果您正在使用內核線程,那么這兩個計算可能會在不同的內核上運行,每個內核都會緩存i
的“值”。 在這種情況下,實際寫入內存的結果是不確定的,因為硬件和編譯器假定沒有人在后面修改數據。
在線程化的情況下,由於可能的數據爭用,有可能獲得1
甚至-1
作為最終值。 由於不能保證線程2完成后將啟動線程2,反之亦然,因此,如果沒有正確的同步,則兩個線程可能幾乎同時啟動並看到初始值0
。 然后,根據哪個線程完成第二秒,該值為1
或-1
而不是0
。 為了避免這種情況,必須使用關鍵部分或原子增量/減量這樣的同步習語。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.