设计了这样一个简单的生产者消费者流程,大家看看这个小问题
设计了这样一个简单的生产者消费者流程,大家看看这个小问题:
一个生产者:
收到消息后,将消息插入全局队列,并SetEvent。
十个消费者:
都在等待那个事件,WaitForSingleObject,如果成功,则从全局队列中取出一个消息节点。
全局队列:
使用STL的deque,在头部插入,在尾部读取,所有与此队列有关的操作使用一个临界区进行保护,其中保存的是一个个的 CInfo*,指向的对象由生产者在堆上创建。
代码如下:
插入节点的C++代码:
{
// lock
MY_LOCK lock(&m_csQueue);
// insert new element
m_queUInfo.push_front(pInfo);
// 插入后通知消费者线程
::SetEvent(m_hEvent);
}
取出一个节点的C++代码:
{
// 锁
MY_LOCK lock(&m_csQueue);
// 取
CInfo* pTemp = NULL;
if (!m_queUInfo.empty())
{
pTemp = m_queUInfo.back();
m_queUInfo.pop_back();
}
// 如果队列中还有元素
if (!m_queUInfo.empty())
{
::SetEvent(m_hEvent);
}
return pTemp;
}
现在问题出现了:
生产者每秒钟向队列中插入大量数据(目前速率是一秒钟1000条记录),10个消费者来取,但是我发现偶尔一些消费者取出的节点是NULL的,现象上看,似乎这些消费者等到了event通知,但是去取时,发现已经没有数据了或者取出的是NULL。实际上所有数据都已经收到了,只是有些消费者线程白等了一把,1%的概率吧,虽然对结果没影响,但是浪费了线程资源,不爽啊。或者是不是STL的deque的用法有问题?
请大家帮忙分析,看看哪里出了问题。分不多了,全给大家了。