[問題] thread會將值存在register中不寫回?
這個問題是出自"程式設計師的自我修養"這一本書
裡面28頁陳述了一個問題
x = 0;
Thread1 Thread2
lock(); lock();
x++; x++;
unlock(); unlock();
書上說可能thread1做完x++時,這個x=1的值還留在register中還沒寫回,
之後換thread2跑完,很久之後thread1才把此值寫回,最後x的值是1
但書上這個例子看起來就是一般multithread用mutex鎖住一段code的寫法,
目前也沒看過這種寫法發生錯誤
請問這個情況什麼時候會發生?
還是說平常在用的unlock會自動把register中的值flush出去?
我把28頁照片放上來
https://photos.app.goo.gl/QYG5LffdJLUC9PfA8
(特別查了一下著作權法,放個一頁應該是沒什麼問題@@)
著作權法第五十二條規定:「
為報導、評論、教學、研究或其他正當目的之必要,在合理範圍內,
得引用已公開發表之著作。」
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 36.227.78.148
※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1539513961.A.CDA.html
推
10/14 19:10,
5年前
, 1F
10/14 19:10, 1F
→
10/14 20:14,
5年前
, 2F
10/14 20:14, 2F
→
10/14 20:14,
5年前
, 3F
10/14 20:14, 3F
→
10/14 20:30,
5年前
, 4F
10/14 20:30, 4F
※ 編輯: Arton0306 (36.227.78.148), 10/14/2018 20:36:06
→
10/14 20:38,
5年前
, 5F
10/14 20:38, 5F
→
10/14 20:40,
5年前
, 6F
10/14 20:40, 6F
→
10/14 20:40,
5年前
, 7F
10/14 20:40, 7F
→
10/14 20:46,
5年前
, 8F
10/14 20:46, 8F
→
10/14 20:48,
5年前
, 9F
10/14 20:48, 9F
→
10/14 20:54,
5年前
, 10F
10/14 20:54, 10F
→
10/14 21:33,
5年前
, 11F
10/14 21:33, 11F
→
10/14 21:38,
5年前
, 12F
10/14 21:38, 12F
我想它這段真的是沒有寫很清楚,以下是我的理解:
它說「落後的編譯器技術已經無法滿足日益增長的並行需求,很多看似無錯的程式碼
在最佳化和並行面前又產生了麻煩,最簡單的例子…(就是我上面寫的code)」
也就是它舉了一個compiler最佳化出bug的例子,
在它的例子中
x+1的值留在register中,不是lock前就存進暫存器,
而是因為有可能之後會再用到,這樣比較快
singlethread是可以這麼做,
但在multithread的情況下,這樣的最佳化是compiler的bug
而它28頁最下方和29頁的例子是code真的有問題 compiler不可能解決
2個例子擺在一起容易誤會
※ 編輯: Arton0306 (36.227.78.148), 10/14/2018 23:09:24
→
10/14 23:38,
5年前
, 13F
10/14 23:38, 13F
推
10/15 01:19,
5年前
, 14F
10/15 01:19, 14F
→
10/15 02:18,
5年前
, 15F
10/15 02:18, 15F
→
10/15 02:28,
5年前
, 16F
10/15 02:28, 16F
→
10/15 02:28,
5年前
, 17F
10/15 02:28, 17F
→
10/15 02:28,
5年前
, 18F
10/15 02:28, 18F
推
10/15 13:05,
5年前
, 19F
10/15 13:05, 19F
感謝 原來後來加進standard了
想到一段以前寫過的code
bool isStop = false; // global var
thread 1 thread 2
while (!isStop) { do something...
do something isStop = true
}
也就是thread1 重複做某件事 直到thread2設定了isStop的flag
例如用在gui取消/中斷某個耗時的計算
現在回想起來
isStop沒有用lock包起來是否有問題??
如果加上volatile 而沒有lock 這樣是否安全?
※ 編輯: Arton0306 (36.227.78.148), 10/16/2018 01:59:34
→
10/16 09:44,
5年前
, 20F
10/16 09:44, 20F
→
10/16 09:44,
5年前
, 21F
10/16 09:44, 21F
→
10/16 09:45,
5年前
, 22F
10/16 09:45, 22F
推
10/16 22:12,
5年前
, 23F
10/16 22:12, 23F
→
10/17 10:47,
5年前
, 24F
10/17 10:47, 24F
→
10/17 10:48,
5年前
, 25F
10/17 10:48, 25F
我發現我原本寫的thread 1的while (isStop)寫錯了
改了while (!isStop) 才對
我上面的例子只有2個thread,只有thread2才會去寫isStop
※ 編輯: Arton0306 (220.136.4.208), 12/07/2018 01:38:57