我正在编写一个离散模拟,其中来自多个线程的请求值累积在一个集中队列中。每n毫秒,经理就会醒来以处理请求。当管理器醒来时,它应该在单个离散步骤中检索中央队列的所有内容。在处理这些消息时,任何尝试提交到队列的客户端线程都应阻塞。处理完成后,队列重新打开,并且管理器返回睡眠状态。
最好的方法是什么? STM的重试行为并不是我真正想要的。如果使用Chan或MVar,则无法防止客户端在处理过程中使其他请求排队。一种方法是将MVar用作持有队列的Chan上的互斥量。还有其他方法吗?
最佳答案
我必须根据您的预期竞争水平进行基准测试,才能确切地知道最佳解决方案是什么,但这是我的猜测。
无论您的商品类型是什么,请使用包含MVar
的[Item]
。用MVar
初始化newMVar []
。要将元素添加到中央列表,请使用modifyMVar_ (return . (item :))
,其中item
是要添加到列表中的元素。在处理过程的开始处使用takeMVar
,在处理过程的结尾使用putMVar []
。
首先,请注意,这不是内部队列。如果要按添加顺序处理事物,请在提取列表后用reverse
列表。
其次,只要这些是您对MVar
进行的唯一操作,就不会出现竞争条件。这是因为MVar
已完全初始化,并且每个操作都是“获取MVar
的内容,然后放入其他内容”。在等待后面的部分时,操作可能会阻塞,但这不会死锁,并且不会丢失任何更新。
关于haskell - 只需一个单独的步骤即可删除Chan或MVar的内容,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4567750/