[問題] 多執行緒亂數生成都一樣?

看板C_and_CPP (C/C++)作者 (麵T)時間10年前 (2015/11/09 20:22), 編輯推噓3(3014)
留言17則, 6人參與, 最新討論串1/1
大家好, 我在 BCB6.0 上原本是想測試執行緒執行效能如何, 但發現這奇怪的現象 CODE: http://ideone.com/HJiA0e 使用多執行緒時, 每次呼叫的亂數總和值 sum 都是 4694505.719100 這是為什麼呢? 在我理解上 rand() 函式很像查亂數表, 整個程式不論 rand() 寫在哪裡, 只要同樣是第 N 次去呼叫 rand(),就會得到相同結果。 if R1 = rand(N), R2 = rand(N) then R1 = R2 所以說執行緒是大家同時去呼叫 rand() ? 可是在程式碼第 29 行 call++ 每個 call 值又不一樣。 另外請教大家, 如果是單核心電腦,使用這樣的程式是不是就沒有 加快執行速度的功能了? 謝謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 110.26.134.74 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1447071728.A.241.html

11/09 20:25, , 1F
rand 不是 thread-safe 的
11/09 20:25, 1F

11/09 20:26, , 2F
要call srand()阿
11/09 20:26, 2F

11/09 20:27, , 3F
啊, 我記錯了, 它是不是 thread-safe 由實作決定
11/09 20:27, 3F

11/09 20:28, , 4F
也就是各線一起呼叫互相有沒有可能有奇怪的影響是不一定的
11/09 20:28, 4F

11/09 20:31, , 5F
單核心跑多線程就一樣是要 context switch
11/09 20:31, 5F

11/09 20:31, , 6F
不奇怪,因為rand()裡面有一個global state亦即seed
11/09 20:31, 6F

11/09 20:31, , 7F
只不過它比 process 的 context switch 輕鬆一點
11/09 20:31, 7F

11/09 20:31, , 8F
實作上如果為了要thread safe又要速度快
11/09 20:31, 8F

11/09 20:31, , 9F
會把seed存在thread local storage
11/09 20:31, 9F

11/09 20:32, , 10F
這麼一來每支thread會有相同的seed,又執行同次數rand
11/09 20:32, 10F

11/09 23:02, , 11F
那為什麼主執行緒自己第一次呼叫(43行)的結果和多執行緒
11/09 23:02, 11F

11/09 23:02, , 12F
不同?
11/09 23:02, 12F

11/10 00:56, , 13F
這叫 race-condition,多人同時"寫"就會這樣
11/10 00:56, 13F

11/10 06:07, , 14F
C的rand是用LCG算出來的 seed一樣同時算就會有一樣的結
11/10 06:07, 14F

11/10 06:07, , 15F
11/10 06:07, 15F

11/10 08:29, , 16F
race condition 就是我所講的"奇怪的影響"之一
11/10 08:29, 16F

11/10 08:30, , 17F
也就是說不只有誰先取誰後取, 還有誰取到一半被打斷的狀況
11/10 08:30, 17F
文章代碼(AID): #1MG8_m91 (C_and_CPP)
文章代碼(AID): #1MG8_m91 (C_and_CPP)