このコードHaskell Concurrent.Channel:この2つのコードの違いは何ですか?
import Control.Monad
import Control.Concurrent
import Control.Concurrent.STM
import Control.Concurrent.STM.TChan
main = do
ch <- newTChanIO
forkIO $ consumer ch 0
forkIO $ consumer ch 1
----------------------
forkIO $ producer ch
----------------------
return()
producer ch = loop 0
where
loop n = do
atomically $ writeTChan ch n
threadDelay (10^5 :: Int)
loop (n+1)
consumer ch n = forever $ do
v <- atomically $ readTChan ch
print (n, v)
は、後者のコードの出力は
(0,0)
(1,1)
(1,2)
(1,3)
(1,4)
(0,5)
(0,6)
(1,7)
...
である。しかし、前者の出力が唯一
あるimport Control.Monad
import Control.Concurrent
import Control.Concurrent.STM
import Control.Concurrent.STM.TChan
main = do
ch <- newTChanIO
forkIO $ consumer ch 0
forkIO $ consumer ch 1
----------------------
producer ch
----------------------
return()
producer ch = loop 0
where
loop n = do
atomically $ writeTChan ch n
threadDelay (10^5 :: Int)
loop (n+1)
consumer ch n = forever $ do
v <- atomically $ readTChan ch
print (n, v)
と同じように動作しないのはなぜは、
(0,0)
producer
は、チャネルキューch
に値を無期限に追加し、consumer
は無制限にch
の値をとることを意図していました。
後者のコードは私の意図と同じように機能しますが、前者のコードは機能しません。イベントログ(GHC-イベント)で
旧コード(forkIO $プロデューサーCH)が無期限に実行されないのはなぜ、ブロックはproducer
スレッドでMVARに
4775372: cap 0: stopping thread 8 (blocked on an MVar)
を発生します。