В следующей программе я хочу, чтобы основной поток не завершался до тех пор, пока все его дочерние потоки не завершат выполнение. Обратите внимание, что я использовал шаблоны взрыва для оценки вызова Фибоначчи, чтобы он возвращал оцененный преобразователь в основной поток.
{-# 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))
Я устал решать эту проблему согласно [ссылке] (Haskell MVar: Как сначала выполнить самое короткое задание?). Я не знаю, правильный ли подход, а также получаю ошибку при попытке напечатать значение 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
Пожалуйста помоги. Спасибо.
STM
транзакций, которые выполняют одно чтение или одну запись вTVar
. Это выглядит странно. Нет никаких гарантий по порядку этих записей w.r.t. чтения, поэтому любое промежуточное значение может быть прочитано, например.10,10,10
. - person chi   schedule 19.01.2015threadDelay (10^6 * 4) nv <- readTVarIO n putStrLn ("Fib number of " ++ " = " ++ (show nv))
, то показывает последнее обновленное значение, т.е. 832040 (Fib 30). В противном случае он показывает значения как 10 610 и 610 (610 — значение Фибоначчи 15). - person Ammlan Ghosh   schedule 19.01.2015IOVar
s вместоTVar
s - вы на самом деле не используете здесь транзакции. - person chi   schedule 19.01.2015