简体   繁体   English

TVar和TMVar之间的区别

[英]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是一个简单的容器,而TMVarMVar相同,意味着它有锁等,但在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. TVarSTM的可变引用,代表一般共享状态。 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). 你创建它持有一个值,你可以读取和写入它等。它非常类似于IORefSTRef (无论如何都是相同的)。

  • 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 . TVarTMVar之间的差异并不像它们看起来那么大 - 绝对不能与IORefMVar之间的差异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). (没有额外的锁定)所有重要的东西都已经用STMTVar实现了,所以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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM