开发者

Removing the contents of a Chan or MVar in a single discrete step

I'm writing a discrete simulation where request values from multiple threads accumulate in a centralized queue. Every n milliseconds, a manager wakes up to process requests. When the manager wakes up, it should retrieve all of the contents of the central queue in a single discrete step. While processing these, any client threads attempting to submit to the queue should block. When processing completes, the queue reopens and the manager goes back to sleep.

What's the best way to do this? The retry beha开发者_StackOverflow中文版vior of STM isn't really what I want. If I use a Chan or MVar, there's no way to prevent clients from enqueuing additional requests during processing. One approach is to use an MVar as a mutex on a Chan holding the queue. Are there other ways to do this?


I'd have to benchmark under your expected contention levels to know exactly what the best solution is, but here's my guess.

Use an MVar containing [Item], whatever your item type is. Initialize the MVar with with newMVar []. To add an element to the central list, use modifyMVar_ (return . (item :)), where item is what you are adding to the list. Use takeMVar at the start of the processing pass, and putMVar [] and the end of it.

First, note that this isn't a queue, internally. If you want to handle things in the order they were added, reverse the list after extracting it.

Second, so long as these are the only operations you perform on the MVar, this is free of race conditions. That's because the MVar is initialized full, and each operation is "take the contents of the MVar, put something else in." Operations may block while waiting for the latter part of that, but this can't deadlock and there will be no lost updates.


Isn't there a problem with MVar [a] though? When there are no items to be read we want readers to be blocked, but since the MVar actually contains [] this doesn't happen.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜