[英]Difference between TVar and TMVar
I've seen the TVar
is a simple container, while the TMVar
is the same as an MVar
, meaning it has a lock etc, but within the STM
monad. 我已经看到
TVar
是一个简单的容器,而TMVar
与MVar
相同,意味着它有锁等,但在STM
monad中。 I am wondering why would that be necessary, as the idea of the STM
is to make locks unnecessary. 我想知道为什么这是必要的,因为
STM
的想法是不需要锁。
So which is the one to use if you, say have a type like [Handle]
a list of socket handles that you want to use between threads made by forkIO
? 如果你有一个像
[Handle]
这样的类型,你想在forkIO
制作的线程之间使用套接字句柄的列表,那么哪个是使用的?
It's not really a matter of locking, it's about what the reference means: 这不是锁定的问题,而是关于引用意味着什么:
TVar
is a mutable reference within STM
, representing general shared state. TVar
是STM
的可变引用,代表一般共享状态。 You create it holding a value, you can read and write to it, etc. It's very much akin to IORef
or STRef
(which are the same thing anyway). 你创建它持有一个值,你可以读取和写入它等。它非常类似于
IORef
或STRef
(无论如何都是相同的)。
TMVar
is a reference to a slot that threads can use to communicate. TMVar
是对线程可用于通信的插槽的引用。 It can be created holding a value, or empty. 它可以创建一个值,也可以为空。 You can put a value into it, which if already filled blocks until someone else empties it;
你可以在其中放入一个值,如果已经填充了块,直到有人将其清空; or you can take a value from it, which if already empty blocks until someone fills it.
或者你可以从中获取一个值,如果已经是空块,直到有人填充它。 It's obviously akin to an
MVar
, but for many common uses it might be simpler to think of it as a single-element queue used for a communicating producer/consumer pair. 它显然类似于
MVar
,但对于许多常见用途而言,将其视为用于通信生产者/消费者对的单元素队列可能更简单。
In short, TVar
is general shared state, use it if you want atomic updates to data from arbitrary places. 简而言之,
TVar
是一般共享状态,如果您希望从任意位置对数据进行原子更新,请使用它。 TMVar
is a synchronization primitive, use it if you want a thread to wait until something becomes available, while another waits for something to be needed. TMVar
是一个同步原语,如果你想让一个线程等到某个东西可用,而另一个等待需要的东西,则使用它。
Also note TChan
, which is implemented roughly as two TVar
s holding locations in a linked list where each forward link is also a TVar
, and works as an unbounded queue for communication. 还要注意
TChan
,它大致实现为链接列表中的两个TVar
持有位置,其中每个前向链路也是TVar
,并且用作通信的无界队列。
All of these can be used in slightly different ways, of course--you can peek at the value of a TMVar
without removing it, for instance, if you want a scenario where multiple threads all wait for a single resource to become available but it's never "used up". 当然,所有这些都可以以稍微不同的方式使用 - 你可以在不删除它的情况下查看
TMVar
的值,例如,如果你想要一个场景,其中多个线程都等待单个资源变得可用但它是永远不会“用完”。
The differences between TVar
and TMVar
are not so large as they look -- definitely not comparable to the differences between IORef
and MVar
. TVar
和TMVar
之间的差异并不像它们看起来那么大 - 绝对不能与IORef
和MVar
之间的差异IORef
。
While MVar
does indeed provide some locking for thread-safety, TMVar
does nothing interesting! 虽然
MVar
确实为线程安全提供了一些锁定,但TMVar
并没有什么有趣的! (no additional locking) Everything important is already implemented with STM
and TVar
, so TMVar a
is just a short-hand for TVar (Maybe a)
equipped with some nice functions (some of which block using the retry
function). (没有额外的锁定)所有重要的东西都已经用
STM
和TVar
实现了,所以TMVar a
只是TVar (Maybe a)
一个简写,配备了一些不错的功能(其中一些使用retry
功能阻止)。
Whether blocking with retry
is compatible with the spirit of STM
and whether it eliminates some of the STM's advantages (no deadlocks etc.) is a separate question and I would love to see someone more experienced to answer it. 是否阻止
retry
符合STM
的精神,是否它消除了STM的一些优点(没有死锁等)是一个单独的问题,我希望看到有更有经验的人来回答它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.