生产者/消费者-使用高CPU的生产者 [英] Producer / Consumer - Producer using high CPU

查看:137
本文介绍了生产者/消费者-使用高CPU的生产者的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个消费者作为生产者消费者模式的一部分:

I have a consumer as part of the producer consumer pattern:

简化后:

public class MessageFileLogger : ILogger
{
    private BlockingCollection<ILogItem> _messageQueue;
    private Thread _worker;
    private bool _enabled = false;
    public MessageFileLogger()
    {
         _worker = new Thread(LogMessage);
         _worker.IsBackground = true;
         _worker.Start();
    }

    private void LogMessage()
    {
        while (_enabled)
        {
            if (_messageQueue.Count > 0)
            {

                itm = _messageQueue.Take();
                processItem(itm);
            }
            else
            {
                Thread.Sleep(1000);
            }
        }
    }
}

如果我删除了

Thread.Sleep(1000);

通过将CPU使用率设置为0%,CPU使用率将攀升至极高的水平(13%)。

The CPU usages climbs to something extremely high (13%) as opposed to 0%, with setting the thread to sleep.

此外,如果我实例化该类的多个实例,则每个实例的CPU使用率将以13%的增量攀升。

Also, if I instantiate multiple instances of the class, the CPU usage climbs in 13% increments, with each instance.

大约每分钟(也许每30秒)向BlockingCollection添加一个新的LogItem,并将适用的消息写入文件。

A new LogItem is added the BlockingCollection about every minute or so (maybe every 30 seconds), and writes an applicable message to a file.

是否有可能该线程以某种方式阻止了其他线程的运行,而系统又以某种方式需要补偿?

Is it possible that the thread is somehow blocking other threads from running, and the system somehow needs to compensate?

更新:
更新了代码以更好地反映实际情况代码

Update: Updated code to better reflect actual code

推荐答案

您已给出了要运行的线程代码,因此默认情况下,它以与之一样快的速度运行该代码(while循环)可能可以在单个逻辑核心上。既然大约占13%,我想您的CPU有4个超线程内核,因此有8个逻辑内核。每个线程都尽可能快地在其内核中运行它的while循环,从而导致另外13%的使用率。真的很简单。

You gave the thread code to run, so by default it runs that code (the while loop) as fast as it possibly can on a single logical core. Since that's about 13%, I'd imagine your CPU has 4 hyperthreaded cores, resulting in 8 logical cores. Each thread runs it's while loop as fast as it possibly can on it's core, resulting in another 13% usage. Pretty straightforward really.

不使用睡眠的副作用是整个系统运行速度较慢,并且使用/产生的电池/热量明显增加。

Side effects of not using sleep are that the whole system runs slower, and uses/produces SIGNIFICANTLY more battery/heat.

通常,正确的方法是为 _messageQueue 提供另一种方法

Generally, the proper way is to give the _messageQueue another method like

bool BlockingCollection::TryTake(type& item, std::chrono::milliseconds time)
{
    DWORD Ret = WaitForSingleObject(event, time.count());
    if (Ret)
        return false;
    item = Take(); //might need to use a shared function instead of calling direct
    return true;
}

然后循环很简单:

private void LogMessage()
{
    type item;
    while (_enabled)
    {
        if (_messageQueue.Take(item, std::chrono::seconds(1)))
            ;//your origional code makes little sense, but this is roughly the same                
        processItem(itm);
    }
}

这也意味着如果在任何位置添加了项点在阻止部分,它会立即作用于 ,而不是一秒钟之后。

It also means that if an item is added at any point during the blocking part, it's acted on immediately instead of up to a full second later.

这篇关于生产者/消费者-使用高CPU的生产者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆