メインスレッドが計算のために新しいスレッドをフォークし、一定の期間終了するのを待つプログラムを作成したいと思います。子スレッドが所定の時間内に完了しない場合、タイムアウトして強制終了されます。これには次のコードがあります。
import Control.Concurrent
fibs :: Int -> Int
fibs 0 = 0
fibs 1 = 1
fibs n = fibs (n-1) + fibs (n-2)
main = do
mvar <- newEmptyMVar
tid <- forkIO $ do
threadDelay (1 * 1000 * 1000)
putMVar mvar Nothing
tid' <- forkIO $ do
if fibs 1234 == 100
then putStrLn "Incorrect answer" >> putMVar mvar (Just False)
else putStrLn "Maybe correct answer" >> putMVar mvar (Just True)
putStrLn "Waiting for result or timeout"
result <- takeMVar mvar
killThread tid
killThread tid'
上記のプログラムをghc -O2 Test.hsandでコンパイルしてghc -O2 -threaded Test.hs実行しましたが、どちらの場合も、プログラムは何も出力したり終了したりせずにハングします。ブロックのthreadDelay (2 * 1000 * 1000)前に計算スレッドにaを追加するとif、タイマースレッドがを埋めることができるため、プログラムは期待どおりに動作し、1秒後に終了しmvarます。
スレッドが期待どおりに機能しないのはなぜですか?
MVar規律は、ここで私には罰金を探します。
+RTS -Nか?詳細については、wiki.haskell.org / Concurrencyを確認してください
MVar競合状態の影響を受けやすいという状態に関するメモ。私はそのことを真剣に受け止めます。