Cli*_*ton 39 concurrency haskell deadlock stm
我最近问了很多关于的问题TVar,我仍然对活锁感到担忧.
所以我想到了这个结构:
TVar).然而,B保持其当前重试的优先级. 我相信这个系统可以防止死锁,但也可以防止饥饿(不像TVar).我想知道是否有人实施了这样的系统,因为它看起来相当明显,我不想重新发明轮子.
当然,可以容易地扩展这种方法以允许用户指定优先级.
优先级可能是一对(user_supplied_prio, auto_increment),与user_supplied_prio采取优先次序,但相同优先级的任务以FIFO的顺序解决.
评论/解决方案:
实际上,当我想到它时,我所描述的已经存在于Haskell中,只需使用一个IORef包裹所有数据,并且仅使用atomicModifyIORef.这atomicModifyIORef将确保按顺序应用交易.但是,有人可能认为这意味着数据结构是顺序的(即有效地限于一个线程),但由于懒惰,它实际上是并行的.
要解释这一点,请考虑一个昂贵的功能f.我们将Data.Map使用键"foo" 将其应用于数据.
这取代(foo -> x)了(foo -> future(f x)).这个帖子应该继续解决(f x)实际问题,但在此期间我们可以将g应用于"bar".由于将g应用于"bar"不需要"foo"的结果,我们可以同时解决这个问题.
没有死锁,没有饥饿,最终将处理所有交易(大致按照收到的顺序).
您可以设置一个工作线程来以确定的方式处理所有请求,这样就不会有人挨饿。这种策略相当有效并且不受活锁的影响。
-- yes, this is a horrible name
createManagerFactory :: a -> IO ((IO a), IO (((a -> a) -> IO a)))
Run Code Online (Sandbox Code Playgroud)
IO a 是通过只读 STM 操作安全快速地查询值的操作。(a -> a) 是一个修改值的纯函数,因此 ((a -> a) -> IO a) 是一个采用修饰符函数、安全地修改值并返回新值的操作。
运行一次以初始化工厂。
(query, modifierFactory) <- createManagerVactory initValue
Run Code Online (Sandbox Code Playgroud)
然后为每个线程运行此命令以生成一个新的修饰符。
myModify <- modifierFactory
Run Code Online (Sandbox Code Playgroud)
createManagerFactory 将执行以下操作:
ModifierFactory 会这样做:
工作线程将运行此循环:
| 归档时间: |
|
| 查看次数: |
1144 次 |
| 最近记录: |