我已经看到TVar
是一个简单的容器,而TMVar
与MVar
相同,这意味着它具有锁等,但在STM
monad中。我想知道为什么这是必要的,因为STM
的想法是不必使用锁。
那么,如果您说有像[Handle]
这样的类型,并且要在forkIO
生成的线程之间使用的套接字句柄列表,那么该使用哪一个?
最佳答案
这实际上并不是锁定的问题,而是关于引用的含义:
TVar
是STM
中的可变引用,表示常规共享状态。创建包含值的文件,可以对其进行读写,等等。这与IORef
或STRef
(两者都是一样)非常相似。 TMVar
是对线程可用于通信的插槽的引用。可以创建一个保存值或为空的值。您可以在其中添加一个值,如果该值已被填充,直到有人将其清空为止。或者,您可以从中获取一个值,如果该值已经为空,则会阻塞直到有人填满它。它显然类似于MVar
,但是对于许多常见用途,将其视为用于生产者/消费者对通信的单元素队列可能更简单。 简而言之,
TVar
是常规共享状态,如果您希望对任意位置的数据进行原子更新,请使用TMVar
。 TChan
是一个同步原语,如果您想让一个线程等待直到某个东西变得可用,而另一个等待一个需要的东西,请使用它。还要注意
TVar
,它大致实现为链接列表中两个TVar
的保存位置,其中每个前向链接也是TMVar
,并且充当通信的无限制队列。当然,所有这些方式都可以以略有不同的方式使用-例如,您可以在不删除ojit_code的情况下窥视ojit_code的值,例如,如果您希望多个线程都在等待单个资源变为可用的情况,从未“用完”。
关于haskell - TVar和TMVar之间的区别,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6915079/