为什么MVar不能与`par`一起使用?

问题描述:

只是好奇。如果我有使用forkIO产生的2个线程,它们之间的通信可以使用MVar来完成。我不知道在使用使用par创建的并行Haskell的火花时是否同样适用。据我所知,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) 

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

不,这不是真的有可能。 MVar是手动控制线程时使用的显式非确定性通信机制。 par火花是一个更高层次的抽象,GHC运行时为您处理通讯。

当您尝试触发IO操作时,没有任何反应,因为触发的操作只能是纯计算。

+0

谢谢。只是引发行动的部分可以是纯粹的帮助! :) – vis 2012-07-05 20:26:48

+0

此外,即使你在spark中的unsafePerformIO,火花不会充当垃圾收集的根源,并且可能会被丢弃,所以检查完全在其权限范围内,找不到潜在的作者。 – 2012-07-05 21:23:39

据我所知,一个线程应该首先运行takeMVar,然后putMVar。这样,一个线程阻止其他线程访问MVar。

+0

我不认为这是正确的。考虑你有2个线程,'t1'用'putMVar'和't2'填充到'MVar'中,用'takeMVar'从中读取。如果't1'先运行,它不会被阻塞,因为变量是空的,'t2'也不会。现在,如果't2'首先运行,它会被阻塞,但当't1'放入变量时将被阻塞。所以,哪一个先运行应该无关紧要。无论哪个人发现自己被阻挡,它都会等到它被解锁。 – vis 2012-07-07 21:25:48

+0

嗯,确实.... – 2012-07-07 22:45:49