Haskell STM:在子线程完成执行之前,主线程不会退出

时间:2015-01-19 12:58:01

标签: multithreading haskell stm

在下面的程序中,我希望主线程在其所有子线程完成执行之前不会退出。请注意,我已经使用bang模式来评估Fibonacci调用,以便它将一个评估的thunk返回给主线程。

{-# LANGUAGE BangPatterns #-}

module Main
where

import Control.Concurrent.STM 
import Control.Concurrent
import System.IO

nfib :: Int -> Int
nfib n | n <= 2 = 1
       | otherwise = (n1 + n2 )
                     where n1 = nfib (n-1)
                           n2 = nfib (n-2)

type TInt = TVar Int

updateNum :: TInt -> Int -> STM()
updateNum n v = do writeTVar n v

updateTransaction :: TInt -> Int -> IO ()
updateTransaction n v = do 
        atomically $ do
             updateNum n v

main :: IO ()
main = do 
    n <- newTVarIO 10

    forkIO $ do             
        let v = 30
        let !x = nfib v
        updateTransaction n x

    forkIO $ do             
        let v = 15
        let !x = nfib v
        updateTransaction n x

    forkIO $ do             
        let v = 25
        let !x = nfib v
        updateTransaction n x   

    nv <- readTVarIO n
    putStrLn ("Fib number of "  ++ " = " ++ (show nv))  

    nv <-  readTVarIO n
    putStrLn ("Fib number of "  ++ " = " ++ (show nv))

    nv <-  readTVarIO n
    putStrLn ("Fib number of "  ++ " = " ++ (show nv))

根据[link](Haskell MVar : How to execute shortest job first?),我已经厌倦了解决这个问题。我不知道方法是否正确,并且在尝试打印TMVar的值时也会出错。 这是代码: - (nfib与上面相同)

type TMInt = TMVar Int

updateNum1 :: TMInt -> Int -> STM()
updateNum1 n v = do putTMVar n v

updateTransaction1 :: TMInt -> Int -> IO ()
updateTransaction1 n v = do 
        atomically $ do
            updateNum1 n v

main1 :: IO ()
main1 = do 
    n <- newTMVarIO 0
    forkIO $ do             
        let v = 30
        let !x = nfib v
        updateTransaction1 n x

    forkIO $ do             
        let v = 15
        let !x = nfib v
        updateTransaction1 n x

    forkIO $ do             
        let v = 25
        let !x = nfib v
        updateTransaction1 n x  

    -- t <- takeTMVar n
    -- putStrLn( "result: " ++ (show t))

**错误如下: -

Couldn't match type `STM' with `IO'
Expected type: IO Int
     Actual type: STM Int
In the return type of a call of `takeTMVar'
In a stmt of a 'do' block: t <- takeTMVar n

请帮忙。谢谢。

1 个答案:

答案 0 :(得分:2)

main1位于IOtakeTMVar返回STM Int。您需要运行该事务:

t <- atomically $ takeTMVar n
putStrLn( "result: " ++ (show t))