Lan*_*nbo 43 concurrency haskell stm
我已经看到它TVar
是一个简单的容器,而它TMVar
是一个MVar
,意思是它有一个锁等,但在STM
monad中.我想知道为什么这是必要的,因为想法STM
是不需要锁.
那么,如果你有一个类似于[Handle]
你想要在线程之间使用的套接字句柄列表的类型,那么哪个是使用的forkIO
?
C. *_*ann 43
这不是锁定的问题,而是关于引用意味着什么:
TVar
是一个可变的引用STM
,代表一般的共享状态.你创建它持有一个值,你可以读取和写入它等.它非常类似于IORef
或STRef
(无论如何都是相同的).
TMVar
是对线程可用于通信的插槽的引用.它可以创建一个值,也可以为空.你可以在其中放入一个值,如果已经填充了块,直到有人将其清空; 或者你可以从中获取一个值,如果已经是空块,直到有人填充它.它显然类似于a MVar
,但对于许多常见用途而言,将其视为用于通信生产者/消费者对的单元素队列可能更简单.
简而言之,TVar
是一般共享状态,如果您希望从任意位置对数据进行原子更新,请使用它.TMVar
是一个同步原语,如果你想让一个线程等到某个东西变得可用,就可以使用它,而另一个则等待需要的东西.
还要注意TChan
,它大致实现为TVar
链表中的两个保持位置,其中每个前向链路也是a TVar
,并且用作通信的无界队列.
所有这些都可以以稍微不同的方式使用 - 当然 - 你可以在TMVar
不删除它的情况下查看a的值,例如,如果你想要一个场景,其中多个线程都等待单个资源变得可用,但它永远不会"用完了".
Rot*_*sor 19
之间的差异TVar
,并TMVar
没有那么大,因为他们看-绝对没有可比性之间的差异IORef
和MVar
.
虽然MVar
确实为线程安全提供了一些锁定,TMVar
但没有什么有趣的!(没有额外的锁)一切都重要的是已经在执行STM
和TVar
,所以TMVar a
只是一个短手TVar (Maybe a)
配备了一些不错的功能(其中使用块的一些retry
功能).
阻塞retry
是否符合其精神STM
以及它是否消除了STM的一些优势(没有死锁等)是一个单独的问题,我希望看到有更有经验的人来回答它.