ACE_Message_Queue<ACE_MT_SYNCH>::putq ()使用时需要注意的地方

来源:互联网 发布:手机淘宝h5页面签到 编辑:程序博客网 时间:2024/05/17 22:33

函数声明

 template<ACE_SYNCH_DECL >int ACE_Task< ACE_SYNCH_DECL >::putq ( ACE_Message_Block *  ,ACE_Time_Value *  timeout = 0 ) 

timeout参数

timeout参数使用绝对时间,而不是相对时间。使用时我们可以使用ACE_OS::gettimeofday ()获取系统当前时间,再加上一个相对时间来确定超时时间。

ACE_Message_Block::duplicate ()的使用

ACE_Message_Block *mb;…………if (test_task->putq (mb->duplicate (), timeout) < 0){    mb->release ();}mb->release ();

上面的代码在正常情况下不会引起问题。在正常情况下,程序可能运行很多年都不会发现什么问题,但却隐含着一个不容易出现的小问题。代码作者认为,在入队列前先增加了数据块的引用计数,入队成功后,减少1次引用计数,取队列的代码最终再使用完MB后再次release ()降低引用计数时,即可释放数据块;如果入队失败了,在if块中降低1次引用计数,在外面再release一次会释放数据块。实际上这时候悲剧就发生了。if块中的确会降低数据块的引用计数,但同时会设置自己对数据块的指针为0。再次release虽然程序不会报错,但内存却泄露了。因为duplicate浅拷贝,会动态分配一个ACE_Message_Block对象,这个对象中保留着对数据块的引用计数,因此数据块和浅拷贝动态分配的ACE_Message_Block都得不到释放。

这个问题隐藏的比较深,if块在正常的逻辑流程中不会走到。