关于ACE_Task::last_thread()
2006-06-30 12:16
253 查看
关于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...
}
这个方法可能会出现在ACE 5.5.2中。
在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...
}
这个方法可能会出现在ACE 5.5.2中。
相关文章推荐
- 关于org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor的队列
- 关于spring线程池ThreadPoolTaskExecutor的作用
- 关于ace_task中wait函数一直没有返回一种解决方法(正解)
- ACE多线程编程工作(ACE_Thread_Manager,ACE_Task_Base,ACE_Task)
- Hadoop MapReduce之ReduceTask任务执行(二):GetMapEventsThread线程
- 【兴趣爱好】之:Boost.Asio和ACE之间关于Socket编程的比较
- 改善C#程序的建议9:使用Task代替ThreadPool和Thread
- 使用Task代替ThreadPool和Thread
- Thread,ThreadPool,Task, 到async await 的基本使用方法和理解
- 关于MBP 加载菊花 崩溃到 MBP.m 报: MBProgressHUD needs to be accessed on the main thread.
- 关于android.view.ViewRoot$CalledFromWrongThreadException 异常
- C#中的thread和task之 Thread & ThreadPool
- ACE利用ACE_Thread_Mutex实现线程间互斥访问临界区
- 【Android】关于FLAG_ACTIVITY_NEW_TASK 和 taskAffinity
- SPRING中的线程池ThreadPoolTaskExecutor
- Scheduler & Task & Worker & Thread & Request & Session & Connection of SQL Server
- 线程池ThreadPool及Task调度死锁分析
- Thread,Task,async/await,IAsyncResult
- 关于C#中Thread.Join()的一点理解
- 关于Calling View methods on another thread than the UI thread的错误