ฉันกำลังทำการทดลองกับการมองเห็นพร้อมกันและหน่วยความจำและพบพฤติกรรมแปลก ๆ นี้ (ดูความคิดเห็นในบรรทัด):
module Main
where
import Data.IORef
import Control.Concurrent
import System.CPUTime
import System.IO
main = do
hSetBuffering stdout NoBuffering
r <- newIORef False
putStrLn "forking..." -- PRINTED
forkIO $ f r
threadDelay 1000000
putStrLn "writeIORef" -- NEVER PRINTED
writeIORef r True
threadDelay maxBound
f :: IORef Bool -> IO ()
f r = readIORef r >>= \b-> if b then print "NEVER PRINTED" else f r
ฉันคาดหวังว่าบางที writeIORef
จะไม่ปรากฏให้เห็นในเธรดย่อย แต่ไม่ใช่เพื่อให้เธรดหลักหยุดทำงาน (อย่างเห็นได้ชัด)
รวบรวมบน ghc 7.8.3
cabal exec ghc -- --make -fforce-recomp -O2 -threaded visibility.hs
และวิ่งไปด้วย
./visibility +RTS -N
เกิดอะไรขึ้นที่นี่?
แก้ไข: ดังนั้นเครื่องของฉันมีสองคอร์จริงและคอร์ไฮเปอร์เธรดสองคอร์ ดังนั้นด้วย +RTS -N
GHC จึงมองเห็นความสามารถ 4 อย่าง ตามคำตอบของ Gabriel Gonzalez ฉันลองทำสิ่งต่อไปนี้เพื่อดูว่าตัวกำหนดตารางเวลาอาจวางทั้งสองเธรดบนโปรเซสเซอร์ฟิสิคัลเดียวกันหรือไม่:
module Main
where
import Data.IORef
import Control.Concurrent
import GHC.Conc(threadCapability,myThreadId,forkOn)
main = do
r <- newIORef False
putStrLn "going..."
(cap,_) <- threadCapability =<< myThreadId
forkOn (cap+1) $ f r -- TRIED cap+1, +2, +3....
threadDelay 1000000
putStrLn "writeIORef" -- BUT THIS STILL NEVER RUNS
writeIORef r True
threadDelay maxBound
f :: IORef Bool -> IO ()
f r = readIORef r >>= \b-> if b then print "A" else f r