找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 3663|回复: 0

关于ACE_Task::last_thread()

[复制链接]
发表于 2008-4-20 13:51:46 | 显示全部楼层 |阅读模式
关于ACE_Task::last_thread()
在ACE应用中,我们经常用ACE_Task类实现多线程处理。由于ACE_Svc_Handler从ACE_Task派生,当你写的应用程序使用了Acceptor-Connector框架同时又直接使用ACE_Task,如线程池,这时你会使用到ACE_Task。
因为许多ACE_Task对应是动态分配的,所以,必须在不再需要时把它们正确地释放掉,知道何时可以释放对象,这一点非常重要。C++NPv2第189页描述了当多线程涉及到的task对象在它们退出时,使用ACE_Task::thr_count()方法确定正确释放它们的方法。
在C++NPv2文档中描述的过程并不不安全,这里有一个用例可以说明这一点。原因如下:
ACE在调用ACE_Task::close()挂钩(hook)函数前检查线程计数。
线程锁(task thread)使控制线程计数顺序化,所以不能通过调用ACE_Task::close()达到控制线程数这一目的,这是因为关闭挂勾(close hook)方法会删除task 对象。因此,多个线程检查ACE_Task:: thr_count()的值都为0是可能存在的。
举例来说吧,我们假设这里有两个线程,A和B,这给都要退出。线程A从svc()方法中退出控制,同时,ACE开始线程记录保护(record-keeping)。ACE获得线程锁并把活动线程数从2减为1,接着,ACE释放线程锁并调用task的close()挂钩方法。其间,线程B也从svc()方法中退出。在线程A检查ACE_Task::thr_count()之前,ACE已执行线程B的清楚操作可能导致task的线程计数器从1变为0.如果那样,线程A和B都会看到线程计数器为0,并都试图清理task对象。这一点肯定不是好事.......
发现并指出这一问题是一位长时间使用ACE的用户,Howard Finer,经过一些迭代和试验Howard找到一个解决这一问题的办法,即额外的维护线程计数器,记住到底是哪一个线程真实的把线程计数器从1变为0,(上述例子中的线程B)。这就要求ACE_Task增加一个新的方法 :
ACE_thread_t ACE_Task::last_thread (void) const
所以,在你的代码实现ACE_Task::close()时需要包含如下的检查
if (ACE_OS::thr_equal (ACE_Thread::self (),
                       this->last_thread ()))
  {
    // Do the cleanup here...
  }
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

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

GMT+8, 2024-12-23 13:29 , Processed in 0.017840 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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