我想做的是這樣的事情,每當這些print動作之一發生時,它就會更新計數器,以確保隨后發生的列印動作在任何可能發生的print動作中總是具有正確的順序,這些動作可能發生在計數器顯示的多個執行緒中。我的例子中的問題是,如果IORef在執行緒之間同時被讀取,那么兩個或更多的print動作將具有相同的計數器值。從我讀到的內容來看,使用Data.Atomics.Counter庫似乎可以解決這個問題,但我真的很難理解如何使用它來解決這個問題。有誰能給我看一個例子或者試著給我解釋一下嗎?
main = do
myref <- newIORef 1 :: IO (IORef Int)
void(forkIO (forever $ do ref <- readIORef myref
print ("hi" show (ref))
modifyIORef myref ( 1) ))
void(forkIO (forever $ do ref <- readIORef myref
print ("hey" show (ref))
modifyIORef myref ( 1) ))
forever $ do ref <- readIORef myref
print ("hello" show (ref))
修改IORef myref ( 1)
uj5u.com熱心網友回復:
我將使用一個MVar來實作這個目的。
inc mvar = forever $ do
v <- takeMVar mvar
列印v
putMVar mvar (v 1)
main = do
mvar <- newMVar1
forkIO (inc mvar)
forkIO (inc mvar)
inc mvar
重要的是,print發生在takeMVar和putMVar之間,而MVar是空的;否則另一個執行緒可能會清空MVar并執行其print。
uj5u.com熱心網友回復:
你可以使用atomicModifyIORef'。它看起來會像:
increment ref = forever do
val <- atomicModifyIORef' ref old -> (old 1, old)
print val
main =do
ref <- newIORef0
forkIO $ increment ref
forkIO $ increment ref
增量參考
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/316897.html
標籤:
