TVar和TMVar的区别
我已经看到了TVar
是一个简单的容器,而TMVar
和MVar
是一样的,意思是它有一个锁等,但是在STM
monad中。 我想知道为什么这是必要的,因为STM
的想法是不需要锁。
那么,如果你有一个像[Handle]
types的套接字句柄的列表,你希望在forkIO
之间使用哪个线程呢?
这不是locking的问题,而是关于参考的含义:
-
STM
是一个可变的参考,代表了一般的共享状态。 你创build它持有一个值,你可以读取和写入它,等等。这是非常类似于IORef
或STRef
(这是同样的事情)。 -
TMVar
是线程可用于通信的插槽的引用。 它可以创build一个值,或者为空。 你可以给它一个值,如果已经填满,直到有人清空它; 或者你可以从中获得一个值,如果已经是空的,直到有人填满。 它显然类似于一个MVar
,但是对于许多常见的用途来说,将其看作用于通信生产者/消费者对的单元素队列可能更简单。
简而言之, TVar
是一般的共享状态,如果你想从任意位置对数据进行primefaces更新,就使用它。 TMVar
是一个同步原语,如果你想要一个线程等待某个东西变得可用,而另一个等待需要的东西,就使用它。
还要注意TChan
,它大致实现为链接列表中的两个TVar
的持有位置,其中每个前向链接也是TVar
,并且作为无限的通信队列工作。
当然,所有这些都可以用稍微不同的方式来使用 – 例如,如果您想要一个场景,其中多个线程都等待单个资源变为可用,但您可以查看TMVar
的值而不删除它从来没有“用完”。
TVar
和TMVar
之间的差异并没有看上去那么大 – 绝对没有IORef
和MVar
之间的差异。
虽然MVar
确实为线程安全提供了一些locking,但TMVar
并没有什么意思! (不需要额外的locking)所有重要的东西都已经在STM
和TVar
实现了,所以TMVar a
只是一个很好的function(其中一些使用retry
function的block)的简称。
是否阻塞retry
符合STM
的精神,是否消除了STM的一些优点(没有死锁等)是一个单独的问题,我很乐意看到更有经验的人来回答这个问题。