最適な解決策はリーダー/ライターの関係に依存しますが、を使用するだけで問題を解決できると思いますMVar
。
させて
import System.Clock
import Text.Printf
import Control.Monad
import Control.Concurrent
import Control.Concurrent.MVar
t__ :: Int -> String -> IO ()
t__ id msg = do
TimeSpec s n <- getTime Realtime
putStrLn $ printf "%3d.%-3d - %d %s" (s `mod` 1000) n id msg
reader :: MVar [Int] -> Int -> IO ()
reader mv id = do
t__ id $ "reader waiting"
xs <- readMVar mv
t__ id $ "reader working begin"
threadDelay (1 * 10^6)
t__ id $ "reader working ends, " ++ show (length xs) ++ " items"
writer :: MVar [Int] -> Int -> IO ()
writer mv id = do
t__ id $ "WRITER waiting"
xs <- takeMVar mv
t__ id $ "WRITER working begin"
threadDelay (3 * 10^6)
t__ id $ "WRITER working ends, " ++ show (1 + length xs) ++ " items"
putMVar mv (id: xs)
main = do
mv <- newMVar []
forM_ (take 10 $ zipWith (\f id -> forkIO (f mv id)) (cycle [reader, reader, reader, writer]) [1..]) $ \p -> do
threadDelay (10^5)
p
getLine
出力あり
c:\tmp>mvar.exe +RTS -N20
486.306991300 - 1 reader waiting
486.306991300 - 1 reader working begin
486.416036100 - 2 reader waiting
486.416036100 - 2 reader working begin
486.525191000 - 3 reader waiting
486.525191000 - 3 reader working begin
486.634286500 - 4 WRITER waiting
486.634286500 - 4 WRITER working begin
486.743378400 - 5 reader waiting
486.852406800 - 6 reader waiting
486.961564300 - 7 reader waiting
487.070645900 - 8 WRITER waiting
487.179673900 - 9 reader waiting
487.288845100 - 10 reader waiting
487.320003300 - 1 reader working ends, 0 items
487.429028600 - 2 reader working ends, 0 items
487.538202000 - 3 reader working ends, 0 items
489.642147400 - 10 reader working begin
489.642147400 - 4 WRITER working ends, 1 items
489.642147400 - 5 reader working begin
489.642147400 - 6 reader working begin
489.642147400 - 7 reader working begin
489.642147400 - 8 WRITER working begin
489.642147400 - 9 reader working begin
490.655157400 - 10 reader working ends, 1 items
490.670730800 - 6 reader working ends, 1 items
490.670730800 - 7 reader working ends, 1 items
490.670730800 - 9 reader working ends, 1 items
490.686247400 - 5 reader working ends, 1 items
492.681178800 - 8 WRITER working ends, 2 items
リーダー 1、2、および 3 は同時に実行され、4 WRITER working begin
次の要求がそれを待機しますが、1、2、および 3 は終了する可能性があります。
(この例では、stdout の出力と FIFO に入るプロセスの順序は正確ではありませんが、読み取られた、または決済されたアイテムの数は実際の順序を示しています)