找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 9782|回复: 7

ACE_Message_Queue会无故阻塞?是不是有bug?

  [复制链接]
发表于 2011-3-20 13:57:50 | 显示全部楼层 |阅读模式
声明了ACE_Message_Queue<ACE_MT_SYNCH>的一个实例q,
然后设置了(相同的)高、低水位:
low_water_mark(1048576);
high_water_mark(1048576);

在一个线程中出队列(消费),
在另一个线程中入队列(生产),如果队列满,则返回-1,不阻塞,如下所示:
ACE_Time_Value tv = ACE_Time_Value::zero;
q->enqueue_tail(pmb, &tv);

每个message block大约几十K字节,每秒钟大约十几个数据块。

运行时发现有时候会阻塞在entueue_tail这句。出现的概率不定,有时候运行几小时出现,有时运行十几个小时才出现。

google上说ACE的message queue有bug,会引发deadlock,但只是在使用了notify的时候,我的应用并没有使用notify。
是不是ACE的message queue有其它bug?或者high_water_mark和low_water_mark设置得不对?各位有没有遇到这类问题?
请各位大侠帮忙,谢谢
发表于 2011-3-20 14:27:47 | 显示全部楼层
这个问题感觉挺难判断根源。我说一下自己以前的一个经典案例,你能搜索到:也是队列阻塞,百思不得其解,找遍网络。后来发现,是代码中有引用环路,导致了A->B->C->A这样的调用关系,陷入死锁。与队列处理无关。

你可以这样测试一下,把水位调的很小,用压力测试跑,试试看结果。如果发现出问题了,用PE这样的工具来定位一下代码的位置。
 楼主| 发表于 2011-3-20 15:10:41 | 显示全部楼层
你的意思是说:ACE_Message_Queue还是比较稳定的,可以放心?
我开始也觉得是环路造成的死锁,找了几天,基本排除了这个可能,因为enqueue_tail是在不持有任何锁的情况下调用的。
所以说比较奇怪。另外ACE的那个由notify引发的deadlock也不知道解决了没有。

现在感觉都不太敢用ACE了,给这个message queue搞怕了, 特别是商业的环境中。
发表于 2011-3-21 23:16:10 | 显示全部楼层
ACE的应用中的确会出现winston 说的循环引用导致的死锁,我在应用中尽量将自己锁的范围缩小,而且避免自己加锁,然后再去调用ace的方法,这样很容易就锁住,而是将在程序进入ACE的代码前将自己的所释放掉。
发表于 2011-3-22 11:34:06 | 显示全部楼层
我不能认定ACE的这个消息队列无问题,但建议仔细排查自己的设计。原来我也是认为ACE有问题,但最终发现问题还是出在自己身上。
发表于 2011-3-22 13:45:49 | 显示全部楼层
可以每次插入后,检查一下队列的元素数量。
我觉得更像是用法问题,应该跟水平位关系不大。
发表于 2011-7-17 15:01:01 | 显示全部楼层
我用的ACE的队列,用了三个,其中两个永远是好的,第三个在用的时候,只要putq()一条数据,很小的一条,我也返回-1,但数据的确进入了队列。。。还没有时间去想为什么呢;
发表于 2011-9-7 15:01:09 | 显示全部楼层
我使用ACE_Message_Queue,每秒处理1000个小时情况下,并没有出现死锁。
一个队列,出现死锁,应该是外部的关系。
因为队列本身就是安全的(加锁的),如果外部在使用队列时,也加了锁,2层锁,不小心很容易死锁。
如果使用线程安全的消息队列,外部就没有必要在使用锁了,如果外部使用了锁,内部就没必要在使用安全队列。
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-5-4 15:23 , Processed in 0.018453 second(s), 7 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表