尽管MVar看起来更加简单,但我觉得TVar更容易使用,而且TVar的功能更加丰富。
所以我的问题很简单,什么情况下我需要使用MVar而非TVar?我想任何时候只要不需要事务更新,就可以使用MVar,但是这样有什么好处呢?
尽管MVar看起来更加简单,但我觉得TVar更容易使用,而且TVar的功能更加丰富。
所以我的问题很简单,什么情况下我需要使用MVar而非TVar?我想任何时候只要不需要事务更新,就可以使用MVar,但是这样有什么好处呢?
MVar
TVar
更快TVar
IORef
TVar
没有什么硬性规定来决定何时使用MVar
或TVar
。
如果我所保护的资源有可能“丢失”(而不是为空,请考虑Nothing
vs Just mempty
),那么MVar
通常是最合适的选择。如果我需要对资源执行原子块修改,则TVar
最合适。
TVars更加安全但速度较慢。
MVars可能会造成死锁,但效率非常高。
而IORef
和atomicModifyIORef
(CAS)的效率更高,但是它的用途受到严格限制。
这实际上是在安全性和性能之间做出的权衡。 TVars是完全通用的,非常安全。 其他所有方法都不如它安全,在一个递减的尺度上。
IORef
将是您最快的操作,但 GHC 7.8 随附了一些对 MVar
的改进,使得 takeMVar/putMVar
与 read/writeIORef
相差仅有几个纳秒(例如在我的机器上为 9.7/4.6 vs 3.7/7/3(<通常的免责声明关于谎言和基准测试>)),而且我们还有一个新的非常快速的 readMVar
(当 MVar 当然是满的)。 - jberrymanTVars
和 modifyIORef
的性能。我做了一个银行账户程序,线程会在两个账户之间进行交易。使用 IORef
实现显然会出现不一致的情况。我第一次尝试对随机数生成器进行基准测试,第二次尝试对更快的随机生成器进行基准测试。第三次尝试中,我的随机生成器实际上并不随机,而是从一个数组中取预生成的数字,这时我发现自己不知道该怎么做,所以放弃了。 - monocell
MVar
来实现多种模式,例如:一些线程放入数据,另一些线程取出数据(本质上是一个一元FIFO队列);许多线程使用modifyMVar
修改共享状态;线程在进入临界区之前获取()
并在退出时替换(将其用作锁)等。 - jberryman