TVar和TMVar的区别

我已经看到了TVar是一个简单的容器,而TMVarMVar是一样的,意思是它有一个锁等,但是在STM monad中。 我想知道为什么这是必要的,因为STM的想法是不需要锁。

那么,如果你有一个像[Handle]types的套接字句柄的列表,你希望在forkIO之间使用哪个线程呢?

这不是locking的问题,而是关于参考的含义:

  • STM是一个可变的参考,代表了一般的共享状态。 你创build它持有一个值,你可以读取和写入它,等等。这是非常类似于IORefSTRef (这是同样的事情)。

  • TMVar是线程可用于通信的插槽的引用。 它可以创build一个值,或者为空。 你可以给它一个值,如果已经填满,直到有人清空它; 或者你可以从中获得一个值,如果已经是空的,直到有人填满。 它显然类似于一个MVar ,但是对于许多常见的用途来说,将其看作用于通信生产者/消费者对的单元素队列可能更简单。

简而言之, TVar是一般的共享状态,如果你想从任意位置对数据进行primefaces更新,就使用它。 TMVar是一个同步原语,如果你想要一个线程等待某个东西变得可用,而另一个等待需要的东西,就使用它。

还要注意TChan ,它大致实现为链接列表中的两个TVar的持有位置,其中每个前向链接也是TVar ,并且作为无限的通信队列工作。

当然,所有这些都可以用稍微不同的方式来使用 – 例如,如果您想要一个场景,其中多个线程都等待单个资源变为可用,但您可以查看TMVar的值而不删除它从来没有“用完”。

TVarTMVar之间的差异并没有看上去那么大 – 绝对没有IORefMVar之间的差异。

虽然MVar确实为线程安全提供了一些locking,但TMVar并没有什么意思! (不需要额外的locking)所有重要的东西都已经在STMTVar实现了,所以TMVar a只是一个很好的function(其中一些使用retryfunction的block)的简称。

是否阻塞retry符合STM的精神,是否消除了STM的一些优点(没有死锁等)是一个单独的问题,我很乐意看到更有经验的人来回答这个问题。