В следующей программе число Фибоначчи генерируется из заданного целого числа (сгенерированного случайным образом), и это значение сохраняется в TVar. Поскольку время выполнения для генерации Фибоначчи различно для разных чисел, потоки не будут выполняться последовательно. Я хочу сохранить theadID, возможно, в списке, чтобы проверить шаблон их выполнения. Пожалуйста, помогите мне. Заранее спасибо.
module Main
where
import Control.Parallel
import Control.Concurrent.STM
import Control.Concurrent
import System.Random
import Control.Monad
import Data.IORef
import System.IO
nfib :: Int -> Int
nfib n | n <= 2 = 1
| otherwise = par n1 (pseq n2 (n1 + n2 ))
where n1 = nfib (n-1)
n2 = nfib (n-2)
type TInt = TVar Int
updateNum :: TInt -> Int -> STM()
updateNum n v = do x1 <- readTVar n
let y = nfib v
x2 <- readTVar n
if x1 == x2
then writeTVar n y
else retry
updateTransaction :: TInt -> Int -> IO ()
updateTransaction n v = do atomically $ updateNum n v
incR :: IORef Int -> Int -> IO ()
incR r x = do { v <- readIORef r;
writeIORef r (v - x) }
main :: IO ()
main = do
n <- newTVarIO 10
r <- newIORef 40;
forM_ [1..10] (\i -> do
incR r i
;v <- readIORef r
;forkIO (updateTransaction n v)
)
Я хочу сохранить [TreadID, FibNo] в списке для всех потоков в соответствии с их выполнением. Предположим, T1 выполнил Fib30, T2 Fib35, T3->32 и T4->40. И если последовательность фиксации потоков, таких как T1, T3, T2 и T4, тогда я хочу сохранить T1-35, T3-32, t2-35, t4-40 в списке.
Изменить: по предложению @MathematicalOrchid я изменил updateTrasaction следующим образом:
updateTransaction :: MVar [(ThreadId, Int)] -> TInt -> Int -> IO ()
updateTransaction mvar n v = do
tid <- myThreadId
atomically $ updateNum n v
list <- takeMVar mvar
putMVar mvar $ list ++ [(tid, v)]
Теперь я пытаюсь распечатать значения из этого списка в основном
main :: IO ()
main = do
...
...
m <- newEmptyMVar
...
...
mv <- readMVar m
putStrLn ("ThreadId, FibVal : " ++ " = " ++ (show mv))
В момент исполнения. Значения MVar не могут быть прочитаны и выдает ошибку
Exception: thread blocked indefinitely in an MVar operation
Что делать? Заранее спасибо.
x1 <- readTVar n; …; x2 <- readTVar n
? Вы в курсе, что это совершенно не обязательно? - person Zeta   schedule 03.12.2014else
когда-нибудь будет выполнена? Еслиx1 /= x2
, то GHC автоматически прервет транзакцию. - person MathematicalOrchid   schedule 03.12.2014TVar
не могут изменить свое значение, за исключением случаев, когда это изменение произошло внутри этой транзакции. - person Zeta   schedule 04.12.2014