我已经看到TVar是一个简单的容器,而TMVar与MVar相同,这意味着它有一个锁等,但在STM monad中。我想知道为什么这是必要的,因为STM的想法是让锁变得不必要。
那么,如果您有一个类似于[Handle]的类型,您希望在forkIO创建的线程之间使用套接字句柄列表,那么应该使用哪种类型
发布于 2011-08-03 00:21:00
这实际上不是锁定的问题,而是引用的含义:
TVar是STM中的一个可变引用,表示一般的共享状态。你可以用一个值来创建它,你可以对它进行读写,等等。它非常类似于IORef或STRef (它们是anyway).TMVar对线程可以用来通信的槽的引用)。它可以创建为包含一个值,也可以为空。您可以将一个值放入其中,如果该值已填充,则会阻塞该值,直到其他人将其清空为止;或者,您可以从中获取一个值,如果该值已经为空,则会阻塞该值,直到有人填充它。它显然类似于MVar,但对于许多常见用途来说,将其视为用于通信的生产者/消费者对的单元素队列可能更简单。简而言之,TVar是通用的共享状态,如果您希望从任意位置对数据进行原子更新,请使用它。TMVar是一个同步原语,如果你想让一个线程等待某个东西变得可用,而另一个线程等待需要的东西,就使用它。
还要注意TChan,它大致实现为链表中的两个TVar保持位置,其中每个前向链路也是一个TVar,并且用作通信的无界队列。
当然,所有这些资源都可以以略有不同的方式使用--例如,如果您想要这样一种场景,即多个线程都在等待单个资源变为可用,但该资源从未“用完”,则可以在不删除TMVar的情况下查看其值。
发布于 2011-08-03 08:38:50
TVar和TMVar之间的差异并不像看起来那么大--绝对比不上IORef和MVar之间的差异。
虽然MVar确实为线程安全提供了一些锁定,但TMVar并没有做什么有趣的事情!(没有额外的锁定)所有重要的东西都已经用STM和TVar实现了,所以TMVar a只是TVar (Maybe a)的速记,配备了一些很好的函数(其中一些函数块使用了retry函数)。
使用retry进行阻塞是否符合STM的精神,以及它是否消除了STM的一些优势(没有死锁等)。是一个单独的问题,我希望看到更有经验的人来回答它。
https://stackoverflow.com/questions/6915079
复制相似问题