我正在考虑使用 TVar 在 Web 应用程序中存储某些状态(可以在重新启动时重新创建)。然而,TVar 的争议方面让我感到担忧。看来,频繁的短期运行事务可能会因为不断中断较长的事务而导致它们挨饿。此外,随着更多运行时间较长的事务不断重新启动,这会增加 CPU 的负载,从而进一步增加这些事务的长度。最终我觉得这可能会导致服务器完全无响应。
考虑到这一点,我有以下问题:
(1) TVar(或其他数据类型)可以使用锁,而不是同时尝试/重试。
(2) TVar(或其他数据类型)是否可以有一些不同的争用机制,即“让事务在运行另一个事务之前运行一秒钟”,或者至少保证事务最终会完成(即争用算法防止 starvation 运行时间较长的事务)。
最佳答案
我认为没有办法保证饥饿自由,除非你改变STM系统本身的运行时代码。在我看来,引入锁来避免 TVar 之间的争用违背了 STM 的初衷,因为使用 STM 的全部目的是摆脱经典的基于锁的、容易出错的模式并发编程的方法。
当然,饥饿可能会导致显着的性能损失,但前提是假设如此大的事务实际上是必要的。我试图牢记的一个设计原则是在低粒度级别使用 TVar。例如,不要将整个 Data.Map
放入 TVar
中,这可能会在每次更新条目时导致争用,
您可以使用更 STM 友好的数据结构,例如跳过列表 [1]。
关于Haskell:TVar:防止饥饿,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10099990/