2015-01-27 4 views
7

다음 하스켈 코드에서 메인 쓰레드가 모든 자식 쓰레드가 끝날 때까지 기다리는 방법.메인 쓰레드가 하스켈에서 모든 자식 쓰레드가 끝나기를 기다리는 방법

이 링크의 "프로그램 종료"절에서 주어진대로 forkFinally를 사용할 수 없습니다 : (http://hackage.haskell.org/package/base-4.7.0.2/docs/Control-Concurrent.html).

TMVar를 사용할 때 원하는 결과를 얻습니다. 하지만 저는 TVar로이 작업을하고 싶습니다. 도와주세요. 내가 과거에 무슨 짓을

module Main 
where 
import Control.Monad 
import Control.Concurrent 
import Control.Concurrent.STM 

type TInt = TVar Int 

transTest :: TInt -> Int -> IO() 
transTest n t = do 
    atomically $ do 
     t1 <- readTVar n      
     doSomeJob t 
     t2 <- readTVar n 
     writeTVar n t 

doSomeJob :: Int -> STM() 
doSomeJob t = do 
    x <- newTVar 0 
    let l = 10^6*t 
    forM_ [1..l] (\i -> do 
     writeTVar x i)    

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

    let v = 5 
    forkIO (transTest n v) 

    let v = 3 
    forkIO (transTest n v) 

    let v = 7 
    forkIO (transTest n v) 

    let v = 1 
    forkIO (transTest n v) 


    r <- atomically $ readTVar n 
    putStrLn("Last updated value = " ++ (show r)) 
+0

''대기 '가있는'Control.Concurrent.Thread' 패키지를 사용하십시오. 표준'Control.Concurrent' 스레드는 대기 할 수 없습니다. 이들을 사용하려면 별도의 신호 메커니즘이 필요하며 각 스레드는 "완료되었습니다"라고 명시 적으로보고해야합니다. http://hackage.haskell.org/package/concurrent-extra-0.3/docs/Control-Concurrent-Thread.html –

+0

예제 링크를 제공해 주시겠습니까? 감사. –

+0

이 문제는 2007 Haskell Cafe 스레드에서 논의되었으며, 거기에 몇 가지 예제 코드가 있습니다. [(link)] (https://www.haskell.org/pipermail/haskell-cafe/2007-November/035329 .html) – ErikR

답변

16

각 갈래의 스레드에 대해 조금 MVAR를 만든 다음 맨 끝에, 각 스레드가 MVAR에 더미 값을 넣을 것 같은 그 스레드를 포크로 forkFinally를 사용하는 것이 었습니다 (예 : MVar를 동기화 프리미티브로 사용했습니다.) 나는 그 MVars에 takeMVar를 기다릴 수 있었다.

내가 조금 도우미 함수로 포장이 사용

forkThread :: IO() -> IO (MVar()) 
forkThread proc = do 
    handle <- newEmptyMVar 
    _ <- forkFinally proc (\_ -> putMVar handle()) 
    return handle 

, 코드는 (내가 읽기 전에이었다, 그러나

-- Fork four threads 
threads <- forM [5, 3, 7, 1] (\v -> forkThread (transTest n v)) 

-- Wait for all of them 
mapM_ takeMVar threads 

처럼 뭔가 변경 될 수 있습니다 대부분의 우수 "책 Simon Marlow의"Parallel and Concurrent Programming in Haskell "에서 async 패키지를 알게되었습니다. 패키지뿐만 아니라 모든 일을 담당 추상화를 제공한다, 그래서 당신은 단지

-- Runs 'transTest n {5,3,7,1}' in parallel and waits for all threads 
_ <- mapConcurrently (transTest n) [5, 3, 7, 1] 

... 그것은 또한 (비동기) 예외로 일을 담당 쓸 수 있습니다.

+0

고맙습니다. 간단하고 참으로 유용합니다. –

관련 문제