簡體   English   中英

用戶級和內核級線程中的並發。 為什么輸出不同?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM