2012-07-05 4 views
2

그냥 호기심. forkIO을 사용하여 2 개의 스레드가 생성되면 MVar을 사용하여 통신 할 수 있습니다. par을 사용하여 만든 병렬 하스켈의 스파크를 사용할 때도 똑같이 적용되는지 궁금합니다. 나는 par이 실제 스레드를 만들지 않고 병렬로 일어날 수있는 계산에 대한 포인터를 만든다는 것을 이해합니다.MVar가`par`와 함께 작동하지 않는 이유는 무엇입니까?

다음 코드는 main이 컴파일되어 thread blocked indefinitely in an MVar operation 오류가 발생합니다.

t1 a = putMVar a "Hi" 
t2 a = do 
    v <- takeMVar a 
    print v 

main1 = do 
    a <- newEmptyMVar 
    forkIO (t1 a) 
    forkIO (t2 a) 

main = do 
    a <- newEmptyMVar 
    (t1 a) `par` (t2 a) 

답변

7

I wonder if the same apply when using parallel Haskell's spark created using par

없음 이 정말 할 수 없습니다. MVar은 스레드를 수동으로 제어 할 때 사용하기위한 명시적이고 비 결정적인 통신 메커니즘입니다. par 스파크는 훨씬 높은 수준의 추상화로, GHC 런타임이 통신을 처리합니다.

IO 작업을 시작하려고하면 스파크 작업이 순수한 계산 일뿐이므로 아무 일도 일어나지 않습니다.

+0

감사합니다. 행동을 촉발 한 부분 만이 순수 할 수 있습니다! :) – vis

+0

스파크 내에서 unsafePerformIO가 발생하더라도 스파크가 가비지 콜렉션 루트로 작동하지 않으므로 폐기 될 수 있으므로이 검사는 잠재적 인 작성자를 찾을 수없는 권한입니다. –

0

내가 아는 한, 스레드는 먼저 takeMVar를 실행 한 다음 putMVar를 실행해야합니다. 이렇게하면 스레드가 다른 스레드에 의해 MVar에 대한 액세스를 차단합니다.

+0

나는 이것이 정확하다고 생각하지 않는다. 'putMVar'를 사용하여'MVar'를 채우고'takeMVar'를 사용하여 그것을 읽는't2'라는 2 개의 쓰레드가 있다고 가정하십시오. 't1'가 먼저 실행되면 변수가 비어있을 때 차단되지 않으며't2'도 차단하지 않습니다. 이제't2'가 먼저 실행되면 차단되지만 't1'이 변수에 넣으면 차단 해제됩니다. 따라서 어느 것이 먼저 실행되는지는 중요하지 않습니다. 둘 중 어느 것이 차단되고 자신을 찾으면 블록이 해제 될 때까지 기다립니다. – vis

+0

흠, 실제로 .... –

관련 문제