[英]Difference between TVar and TMVar
我已经看到TVar
是一个简单的容器,而TMVar
与MVar
相同,意味着它有锁等,但在STM
monad中。 我想知道为什么这是必要的,因为STM
的想法是不需要锁。
如果你有一个像[Handle]
这样的类型,你想在forkIO
制作的线程之间使用套接字句柄的列表,那么哪个是使用的?
这不是锁定的问题,而是关于引用意味着什么:
TVar
是STM
的可变引用,代表一般共享状态。 你创建它持有一个值,你可以读取和写入它等。它非常类似于IORef
或STRef
(无论如何都是相同的)。
TMVar
是对线程可用于通信的插槽的引用。 它可以创建一个值,也可以为空。 你可以在其中放入一个值,如果已经填充了块,直到有人将其清空; 或者你可以从中获取一个值,如果已经是空块,直到有人填充它。 它显然类似于MVar
,但对于许多常见用途而言,将其视为用于通信生产者/消费者对的单元素队列可能更简单。
简而言之, TVar
是一般共享状态,如果您希望从任意位置对数据进行原子更新,请使用它。 TMVar
是一个同步原语,如果你想让一个线程等到某个东西可用,而另一个等待需要的东西,则使用它。
还要注意TChan
,它大致实现为链接列表中的两个TVar
持有位置,其中每个前向链路也是TVar
,并且用作通信的无界队列。
当然,所有这些都可以以稍微不同的方式使用 - 你可以在不删除它的情况下查看TMVar
的值,例如,如果你想要一个场景,其中多个线程都等待单个资源变得可用但它是永远不会“用完”。
TVar
和TMVar
之间的差异并不像它们看起来那么大 - 绝对不能与IORef
和MVar
之间的差异IORef
。
虽然MVar
确实为线程安全提供了一些锁定,但TMVar
并没有什么有趣的! (没有额外的锁定)所有重要的东西都已经用STM
和TVar
实现了,所以TMVar a
只是TVar (Maybe a)
一个简写,配备了一些不错的功能(其中一些使用retry
功能阻止)。
是否阻止retry
符合STM
的精神,是否它消除了STM的一些优点(没有死锁等)是一个单独的问题,我希望看到有更有经验的人来回答它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.