ACE_Message_Queue会无故阻塞?是不是有bug?
声明了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设置得不对?各位有没有遇到这类问题?
请各位大侠帮忙,谢谢 这个问题感觉挺难判断根源。我说一下自己以前的一个经典案例,你能搜索到:也是队列阻塞,百思不得其解,找遍网络。后来发现,是代码中有引用环路,导致了A->B->C->A这样的调用关系,陷入死锁。与队列处理无关。
你可以这样测试一下,把水位调的很小,用压力测试跑,试试看结果。如果发现出问题了,用PE这样的工具来定位一下代码的位置。 你的意思是说:ACE_Message_Queue还是比较稳定的,可以放心?
我开始也觉得是环路造成的死锁,找了几天,基本排除了这个可能,因为enqueue_tail是在不持有任何锁的情况下调用的。
所以说比较奇怪。另外ACE的那个由notify引发的deadlock也不知道解决了没有。
现在感觉都不太敢用ACE了,给这个message queue搞怕了, 特别是商业的环境中。 ACE的应用中的确会出现winston 说的循环引用导致的死锁,我在应用中尽量将自己锁的范围缩小,而且避免自己加锁,然后再去调用ace的方法,这样很容易就锁住,而是将在程序进入ACE的代码前将自己的所释放掉。 我不能认定ACE的这个消息队列无问题,但建议仔细排查自己的设计。原来我也是认为ACE有问题,但最终发现问题还是出在自己身上。 可以每次插入后,检查一下队列的元素数量。
我觉得更像是用法问题,应该跟水平位关系不大。 我用的ACE的队列,用了三个,其中两个永远是好的,第三个在用的时候,只要putq()一条数据,很小的一条,我也返回-1,但数据的确进入了队列。。。还没有时间去想为什么呢; 我使用ACE_Message_Queue,每秒处理1000个小时情况下,并没有出现死锁。
一个队列,出现死锁,应该是外部的关系。
因为队列本身就是安全的(加锁的),如果外部在使用队列时,也加了锁,2层锁,不小心很容易死锁。
如果使用线程安全的消息队列,外部就没有必要在使用锁了,如果外部使用了锁,内部就没必要在使用安全队列。
页:
[1]