多核心與同步

以兩個執行緒同時執行上方的程式碼時,counter的最終值有時會小於200000。其原因下列何者正確?

int counter = 0;
// 兩個執行緒同時各自執行
for (int i = 0; i < 100000; i++)
    counter++;
  1. A因為CPU有時會算錯加法
  2. B因為counter++分為讀取、加法、寫入,當兩個執行緒的處理重疊時,其中一方的加法會遺失
  3. C因為迴圈的次數會依執行緒自動減半
查看答案與解析

正確答案:B. 因為counter++分為讀取、加法、寫入,當兩個執行緒的處理重疊時,其中一方的加法會遺失

counter++是從記憶體讀取值、加上1、再寫回記憶體這三個操作。若執行緒A讀到100,在寫回之前執行緒B也讀到100,則兩者都會寫入101,使兩次加法變成只有一次。這是資料競爭的典型例子。只要使用原子加法指令,或以鎖讓一次只有一個執行緒進行更新,就能正確得到200000。

  • A. CPU的運算是正確進行的。
  • B. 正確。兩者都對相同的舊值加1,寫入相同的值。
  • C. 迴圈的次數不會改變。
練習這個領域 前往領域頁面

多核心與同步的其他題目

  1. 關於原子指令(不可分割指令),下列說明何者正確?
  2. 關於原子指令CAS(比較並交換,compare-and-swap)的動作,下列何者正確?
  3. 上方的程式碼使用CAS(&p, 預期值, 新值)將共用變數counter變成2倍。CAS失敗而重做迴圈,是在什麼情況下?
  4. 在RISC-V的LR/SC(載入保留/條件式儲存)這類指令組中,SC(條件式儲存)會在什麼情況下失敗?
  5. 關於使用CAS的無鎖資料結構中會出現的ABA問題,下列說明何者正確?

這個領域的比較