在单个离散步骤中删除Chan或MVar的内容

时间:2010-12-31 02:47:09

标签: haskell

我正在编写一个离散模拟,其中来自多个线程的请求值在集中队列中累积。每隔n毫秒,经理就会醒来处理请求。当经理醒来时,它应该在一个单独的步骤中检索中心队列内容的所有。处理这些时,任何尝试提交到队列的客户端线程都应该阻塞。处理完成后,队列重新打开,管理器重新进入休眠状态。

最好的方法是什么? STM的重试行为并不是我想要的。如果我使用Chan或MVar,则无法阻止客户端在处理期间将其他请求排入队列。一种方法是使用MVar作为持有队列的Chan上的互斥体。还有其他方法吗?

2 个答案:

答案 0 :(得分:5)

我必须在你预期的争用水平下进行基准测试才能确切知道最佳解决方案是什么,但这是我的猜测。

使用包含MVar的{​​{1}},无论您的商品类型是什么。使用[Item]初始化MVar。要将元素添加到中央列表,请使用newMVar [],其中modifyMVar_ (return . (item :))是您要添加到列表中的内容。在处理过程开始时使用itemtakeMVar及其结尾。

首先,请注意,这不是内部队列。如果您想按照添加的顺序处理事情,请在提取后列出putMVar []

其次,只要这些是您在reverse上执行的唯一操作,就没有竞争条件。这是因为MVar已初始化为完整,并且每个操作都是“获取MVar的内容,将其他内容放入其中。”操作可能会在等待后半部分时阻塞,但这不会死锁,并且不会丢失更新。

答案 1 :(得分:1)

虽然MVar [a]没有问题吗?当没有要阅读的项目时,我们希望读者被阻止,但由于MVar实际上包含[],因此不会发生这种情况。