关于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中。
分享到:
相关推荐
static __time64_t __cdecl _make__time64_t ( struct tm *tb, int ultflag ) { __time64_t tmptm1, tmptm2, tmptm3; struct tm tbtemp; long dstbias = 0;... long timezone = 0;...= NULL ), EINVAL, ( ( __time64...
### 分析ACE_Task::putq在队列满且timeout为0的情况 #### 0. 引言 在本文中,我们将深入探讨调用`ACE_Task::putq`函数时的各种行为,尤其是当队列满且`timeout`参数设为0的情况。我们将分析涉及的多个层面,包括...
if (ACE_OS::thr_equal(ACE_Thread::self(), this->last_thread())) { // 清理资源 delete this; } return 0; } virtual int svc(void) { return 0; } }; ``` - `open()`方法:在此方法中通过`activate()`...
- `ACE_OS::last_error()`: 获取最近发生的错误代码。 - `ACE_OS::strerror()`: 将错误代码转换为错误消息字符串。 9. **网络通信** - `ACE_OS::inet_addr()`: 将IP地址字符串转换为二进制表示。 - `ACE_OS::...
- **ACE::strdelete(char*)**: 删除动态分配的字符串空间。 #### 四、总结 ACE框架通过提供丰富的API支持,使得开发者能够方便地实现高性能的服务端应用程序。无论是基于事件驱动的I/O操作,还是定时器管理和信号...
4. `ACE_Thread_Manager`:用于管理线程,确保资源的正确释放。 客户端可能包含以下组件: 1. `ACE_SOCK_Connector`:尝试连接到服务器的指定端口。 2. `ACE_Svc_Handler`:与服务器端类似,处理客户端的I/O事件和...
在提供的代码片段中,`Thread_Pool`类继承自`ACE_Task<ACE_MT_SYNCH>`,其中`ACE_MT_SYNCH`是一个模板参数,表示使用多线程(Multithreaded)和同步(Synchronized)策略。`Thread_Pool`类添加了一些额外的功能,如...
ACE日志服务提供了多种日志输出宏,例如ACE_DEBUG、ACE_INFO、ACE_WARNING、ACE_ERROR等,用于输出不同级别的日志信息。这些宏可以根据需要进行定义和使用,例如: ACE_DEBUG((LM_DEBUG, "This is a debug message...
ACE(Adaptive Communication Environment)是一个跨平台的网络通信框架,由Douglas C. Schmidt领导的团队在1995年开发。它提供了大量的C++模板类和函数,以支持高效、可靠的分布式系统开发。ACE_MFC是ACE框架的一个...
ACE_Task用于定义任务的执行;ACE_Pipes和Filters组件用于创建可插拔和可重用的通信管道。ACE还提供了ACE_Thread类,用于管理线程的生命周期,包括创建、设置优先级、挂起、恢复、取消、同步、等待等。 ACE中的线程...
这个RAR压缩包中的资源,"ACE.chm",是一部关于ACE网络编程的开发说明文档,特别适合初学者入门学习。通过这份文档,你可以深入理解ACE的核心概念和技术,并学会如何在Visual C++环境下进行实际的网络编程。 一、...
ACE(Adaptive Communication Environment,自适应通信环境)是AT&T实验室开发的一个跨平台的C++软件框架,它提供了丰富的网络编程接口,包括进程管理、线程管理、并发控制、I/O复用等。在ACE中,对进程的管理主要...
Ace Reactor是一个基于Ace库开发的高性能网络反应堆,它被设计用于构建高效、可扩展的网络服务。Ace是AT&T实验室开发的一个跨平台、事件驱动的C++网络编程框架,而Ace Reactor是其核心组件,用于处理异步事件和网络I...
例如,ACE_SOCK_Stream的get_last_error()方法可以帮助我们获取错误信息,而ACE_Transport_Cache则可以管理连接状态,自动重连或关闭无效连接。 在“ACE_SOCK_TCP.rar”压缩包中的示例代码“ACE_SOCK_TCP”,可能...
在《ACE并发编程.docx》文档中,你可以找到关于如何创建和使用ACE_Task的详细步骤,包括初始化、消息处理、线程管理和销毁等过程。《ACE_Task类讲解.docx》则可能进一步深入到类的成员函数、接口以及实际应用示例,...
ACE框架提供了一个强大的任务类`ACE_Task`,用于创建和管理线程。该类是所有ACE线程类的基础,继承自`ACE_Task_Base`类。一个典型的ACE线程实例包括以下步骤: 1. **定义一个派生自`ACE_Task_Base`的类**:例如`HA_...
- **ACE_Task_Base**:是所有任务类的基础,提供了基本的任务控制接口。 3. **ACE_Shared_Memory_Pool**:管理共享内存池,用于进程间或线程间的共享数据交换。 - **ACE_Lite_MMAP_Memory_Pool**:轻量级的内存池...
Bootstrap Ace模版1.4是基于流行的前端框架Bootstrap构建的一款高效、美观的后台管理模版。这个版本,标记为"ace_v1.4_2016.3.28.zip",包含了2016年3月28日更新的全部内容,旨在提供丰富的界面元素和组件,方便...
ACE(Adaptive Communication Environment)是一个跨平台的C++库,专为分布式系统和网络编程设计。这个库提供了许多高级服务,如并发处理、线程管理、网络通信、定时器、I/O复用等,使开发者能够高效地构建复杂的、...