Forked IORef读取器功能似乎停止主线程 [英] Forked IORef reader function seems to stall main thread
问题描述
我正在做并发和内存可见性的一些实验,并遇到这种奇怪的行为(见内嵌的评论):
I was doing some experiments with concurrency and memory visibility and ran into this strange behavior (see comments inline):
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
不能对子线程可见,但不能让主线程简单地(显然)停止。
I was expecting perhaps the writeIORef
not to be visible to the child thread, but not for the main thread to simply (apparently) stall.
编译ghc 7.8。 3
Compiled on ghc 7.8.3
cabal exec ghc -- --make -fforce-recomp -O2 -threaded visibility.hs
并运行
./visibility +RTS -N
这里发生了什么?
EDIT :所以我的机器有两个真正的内核和两个超线程内核,因此使用 + RTS -N
GHC看到4个功能。 Per Gabriel Gonzalez的回答我试过以下,看看是否也许调度程序将两个线程放在同一个物理处理器上:
EDIT: So my machine has two real cores and two hyperthreading cores, so with +RTS -N
GHC sees 4 capabilities. Per Gabriel Gonzalez's answer I tried out the following to see if maybe the scheduler was putting both threads on the same physical processor:
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
推荐答案
像这样可能是一个古老的 ghc错误#367 。
It looks like this is probably an ancient ghc bug #367.
这篇关于Forked IORef读取器功能似乎停止主线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!