我已经看到TVar是一个简单的容器,而TMVarMVar相同,这意味着它具有锁等,但在STM monad中。我想知道为什么这是必要的,因为STM的想法是不必使用锁。

那么,如果您说有像[Handle]这样的类型,并且要在forkIO生成的线程之间使用的套接字句柄列表,那么该使用哪一个?

最佳答案

这实际上并不是锁定的问题,而是关于引用的含义:

  • TVarSTM中的可变引用,表示常规共享状态。创建包含值的文件,可以对其进行读写,等等。这与IORefSTRef(两者都是一样)非常相似。
  • TMVar是对线程可用于通信的插槽的引用。可以创建一个保存值或为空的值。您可以在其中添加一个值,如果该值已被填充,直到有人将其清空为止。或者,您可以从中获取一个值,如果该值已经为空,则会阻塞直到有人填满它。它显然类似于MVar,但是对于许多常见用途,将其视为用于生产者/消费者对通信的单元素队列可能更简单。

  • 简而言之,TVar是常规共享状态,如果您希望对任意位置的数据进行原子更新,请使用TMVarTChan是一个同步原语,如果您想让一个线程等待直到某个东西变得可用,而另一个等待一个需要的东西,请使用它。

    还要注意TVar,它大致实现为链接列表中两个TVar的保存位置,其中每个前向链接也是TMVar,并且充当通信的无限制队列。

    当然,所有这些方式都可以以略有不同的方式使用-例如,您可以在不删除ojit_code的情况下窥视ojit_code的值,例如,如果您希望多个线程都在等待单个资源变为可用的情况,从未“用完”。

    关于haskell - TVar和TMVar之间的区别,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6915079/

    10-11 21:36