.NET 消费者线程处理两个队列的算法(基于优先级)

发布于 2024-10-29 01:07:02 字数 471 浏览 5 评论 0原文

我有一个 C# 4.0 应用程序,其“高优先级”和“低优先级”队列的实现如下:

BlockingCollection highPriority = new BlockingCollection(1000); BlockingCollection lowPriority = new BlockingCollection(1000);

在 highPriority 中生成的任何数据都应在 lowPriority 中生成的任何数据之前被消耗。这里的不同之处在于,数据可以随时生成到两个队列中的任何一个。因此,在消耗完 highPriority 中的所有数据后,我将消耗可能处于 lowPriority 中的任何数据。如果当我在 lowPriority 中消费数据时,在 highPriority 中产生新数据,我想完成对 lowPriority 中当前项目的消费,然后切换回并处理 highPriority 中的数据。

谁能建议一种算法来帮助解决这个问题?伪代码没问题。非常感谢。

I have a C# 4.0 app with "high priority" and "low priority" queues implemented as such:

BlockingCollection highPriority = new BlockingCollection(1000);
BlockingCollection lowPriority = new BlockingCollection(1000);

Any data produced in highPriority should be consumed before any data produced in lowPriority. The twist here is that data may be produced to either of the two queues at any time. So after I've consumed all of the data in highPriority, I will then being consuming any data that might be in lowPriority. If new data is produced in highPriority while I'm consuming data in lowPriority, I want to finish consuming the current item in lowPriority and then switch back and process the data in highPriority.

Can anyone suggest an algorithm to help with this? Pseudo code is fine. Thanks very much.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

方觉久 2024-11-05 01:07:02

这个怎么样:

while(true)
{
    workitem = highQueue.dequeue();

    if(workitem == null)
        workitem = lowQueueu.dequeue()

    process(workitem)
}

How about this:

while(true)
{
    workitem = highQueue.dequeue();

    if(workitem == null)
        workitem = lowQueueu.dequeue()

    process(workitem)
}
最丧也最甜 2024-11-05 01:07:02

如果可以的话,您将希望将其包装到单个对象中,正如 @Kevin Brock 建议的那样,并让该对象实现 IProducerConsumerCollection。否则,调用 TryDequeue 的代码将执行繁忙的等待循环。也就是说,有两个队列,你必须这样写:

WorkItem item = null;
do
{
    if (!hpQueue.TryDequeue(out item))
    {
        lpQueue.TryDequeue(out item);
    }
while (item != null);

如果你使用自己的类,那么你可以使用事件(EventWaitHandle等)来防止忙等待。

事实上,使用优先级队列可能会更好。使优先级队列线程安全并实现 IProducerConsumerCollection 非常容易,然后您可以将其与 BlockingCollection 一起使用。 Julian Bucknall 的 C# 中的优先级队列 是一个不错的起点。

You'll want to wrap this into a single object if you can, as @Kevin Brock suggested, and have that object implement IProducerConsumerCollection. Otherwise your code that calls TryDequeue will have do do a busy wait loop. That is, with two queues, you have to write something like:

WorkItem item = null;
do
{
    if (!hpQueue.TryDequeue(out item))
    {
        lpQueue.TryDequeue(out item);
    }
while (item != null);

If you use your own class, then you can use events (EventWaitHandle, etc.) to prevent the busy waiting.

In truth, you'd probably be better off using a priority queue. It would be pretty easy to make a priority queue thread-safe and implement IProducerConsumerCollection, and then you can use it with BlockingCollection. A good place to start would be Julian Bucknall's Priority Queue in C#.

樱花坊 2024-11-05 01:07:02

我会用一个优先级队列来做到这一点。这将允许您稍后添加第三优先级,只需很少的代码更改。

我在使用 lockFree-SkipList 之前写过一个项目,但这里有一个使用普通跳过列表的项目(http://www.codeproject.com/KB/recipes/PriorityQueueSkipList.aspx)。我使用了跳跃列表,因为它们在并发下表现良好并且实现起来非常简单(减去无锁版本)。

我还在 CodePlex 上看到了一个使用红黑树的优先级队列,但我现在找不到它。
更新:我正在考虑的优先级队列实现是 NGenerics 项目的一部分:http://code.google .com/p/ngenerics/

I would do this with a single priority queue. This would allow you to add a 3rd priority later, with very little code change.

I've written one before using a lockFree-SkipList, But here's a project for one which uses a normal skip-list (http://www.codeproject.com/KB/recipes/PriorityQueueSkipList.aspx). I used a skip-list because they preform well under concurrency and are pretty simple to implement (minus the lock-free version).

Ive also seen a priority queue on CodePlex which use a Red-Black Tree, but I can't find it right now.
UPDATE : The priority queue implementation I was thinking of was part of the NGenerics project: http://code.google.com/p/ngenerics/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文