设计了这样一个简单的生产者消费者流程,大家看看这个小问题

wndrfll 2008-10-29 06:30:04
设计了这样一个简单的生产者消费者流程,大家看看这个小问题:

一个生产者:
收到消息后,将消息插入全局队列,并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的用法有问题?
请大家帮忙分析,看看哪里出了问题。分不多了,全给大家了。


...全文
113 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
wndrfll 2008-10-30
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 Gump_BlueSky 的回复:]
如果你的电脑是双核的CPU的话,那问题就在电脑上啦.不过你可以设置mutex试着解决这人问题
[/Quote]

晕死,刚才写了一堆回复,结果没法出去。
我使用过给所有的消费者线程提供一个mutex,发现结果所有的消息都是一个线程来处理了。仔细想想,会不会是因为:一个线程一旦拥有了一个mutux,再次等待这个mutux总是会成功,是可以递归等待的。
是否这个原因呢,还请大侠指点?
另外,这个简单的设计如果是在单核上是没问题的吧?
Gump_BlueSky 2008-10-30
  • 打赏
  • 举报
回复
如果你的电脑是双核的CPU的话,那问题就在电脑上啦.不过你可以设置mutex试着解决这人问题
Gump_BlueSky 2008-10-30
  • 打赏
  • 举报
回复
如果你的电脑是双核的CPU的话,那问题就在电脑上啦.不过你可以设置mutex试着解决这人问题
wndrfll 2008-10-30
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 chendengbiao 的回复:]
Event 运用的问题
[/Quote]

还请深入解释一下。
lin_style 2008-10-29
  • 打赏
  • 举报
回复
不懂WINDOWS,随便问个
::SetEvent(m_hEvent);在锁条件下,发出这句后,是怎么操作的?也是先解开最早的锁和其他语句争夺吗?还是本身的线程不参与这个事件的争夺
chendengbiao 2008-10-29
  • 打赏
  • 举报
回复
Event 运用的问题

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧