我有一个消费者作为生产者消费模式的一部分:
简化:
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使用率上升到非常高的值(13%),而不是0%,将线程设置为睡眠。
另外,如果我实例化了该类的多个实例,那么每个实例的CPU使用量都会增加13%。
一个新的LogItem大约每分钟添加一次BlockingCollection (可能每30秒一次),并将适用的消息写入文件。
线程是否可能以某种方式阻止其他线程运行,而系统需要进行补偿?
更新:更新代码以更好地反映实际代码
发布于 2014-02-26 19:58:09
您让线程代码运行,因此默认情况下,它在单个逻辑核心上尽可能快地运行该代码( while循环)。因为这大约是13%,我可以想象你的CPU有4个超线程核心,从而产生了8个逻辑核。每个线程在内核上尽可能快地运行自己的while循环,从而导致另外13%的使用率。真的很直截了当。
不使用睡眠的副作用是整个系统运行缓慢,并且使用/产生更多的电池/热量。
通常,正确的方法是给_messageQueue另一个方法,如
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);
}
}它还意味着,如果在阻塞部分期间的任何点添加了一个项,那么它将被立即操作,而不是在稍后的整整一秒钟内被执行。
https://stackoverflow.com/questions/22051545
复制相似问题