ACE中线程的实现原理

摘自:http://www.acejoy.com/bbs/dispbbs.asp?boardID=23&ID=840&page=4

向ACE的高手们学习致敬!

=========================================================================

ACE中线程的实现原理
1.ACE中对线程的封装
1.1ACE_Thread实现原理
ACE_Thread 提供了对OS 的线程调用的简单包装,这些调用处理线程创建、挂起、取消和删除等问题。它提供给应用程序员一个简单易用的接口,可以在不同的线程API 间移植。ACE_Thread 是非常“瘦”的包装,有着很少的开销。其大多数方法都是内联的,因而等价于对底层OS 专有线程接口的直接调用。ACE_Thread 中的所有方法都是静态的,而且该类一般不进行实例化。
ACE_Thread类中的几个重要的静态函数:
1)建立线程:
size_t spawn_n (size_t n,
                         ACE_THR_FUNC func,
                         void *arg = 0,
                         long flags = THR_NEW_LWP | THR_JOINABLE,
                         long priority = ACE_DEFAULT_THREAD_PRIORITY,
                         void *stack[] = 0,
                         size_t stack_size[] = 0,
                         ACE_Thread_Adapter *thread_adapter = 0)
     {
         …
         for (i = 0; i < n; i++)
         // Bail out if error occurs.
              if (ACE_OS::thr_create (func,
                            arg,
                            flags,
                            &t_id,
                            0,
                            priority,
                            stack == 0 ? 0 : stack[i],
                            stack_size == 0 ? 0 : stack_size[i],
                            thread_adapter) != 0)
                   break;
         return i;
}
该函数可以同时创建n个线程。该函数在中途遇到创建线程失败的情况出现时会自动跳出,而不继续创建。
size_t ACE_Thread::spawn_n (ACE_thread_t thread_ids[],
                     size_t n,
                     ACE_THR_FUNC func,
                     void *arg,
                     long flags,
                     long priority,
                     void *stack[],
                     size_t stack_size[],
                     ACE_hthread_t thread_handles[],
                     ACE_Thread_Adapter *thread_adapter)
该函数可以使用thread_ids[]记录所有创建成功的线程的id号。
而对于spawn函数则只能够创建单个线程。
1.2ACE_Task_Base实现原理
ACE_Task_Base 是ACE 中的任务或主动对象“处理结构”的基类。在ACE 中使用了此类来实现主动对象模式。所有希望成为“主动对象”的对象都必须从此类派生。你也可以把ACE_TASK 看作是更高级的、更为面向对象的线程类。
ACE_Task_Base调用时必须重写svc方法,并且在使用时保证调用了activate方法。
最常见的使用流程如下例:
class TaskOne: public ACE_Task_Base
{
public:
//Implement the Service Initialization and Termination methods
int open(void*)
{
activate();
return 0;
}
int close(u_long)
{
return 0;
}
int svc(void)
{
// do thread specific work here
//.......
//.......
return 0;
}
};
int main(int argc, char *argv[])
{
//Create the task
TaskOne *one=new TaskOne;
//Start up the task
one->open(0);
//wait for all the tasks to exit
ACE_Thread_Manager::instance()->wait();
ACE_DEBUG((LM_DEBUG,"(%t) Main Task ends /n"));
}
ACE_Task_Base中的关键方法:
①open 
用户改写该函数,在其中调用ACE_Tase_Base::activate()方法。
②svc  
    用户必须重新实现该方法,用于供线程调用。
③close
    用户可以修改该函数用于完成在线程结束前的清理工作。
④svc_run
    该方法为静态函数,作为线程的回调函数。该函数中调用了svc方法。这里有一个技巧ACE_Task_Base在实现svc_run函数时将ACE_Task_Base类的对象以参数形式传进了svc_run方法中:
ACE_Task_Base::activate(…)
{
    …
        //第三个参数为传入回调函数的参数指针。
          this->thr_mgr_->spawn_n (n_threads,
                               &ACE_Task_Base::svc_run,
                               (void *) this,
                               flags,
                               priority,
                               grp_id,
                               task,
                               thread_handles,
                               stack,
                          stack_size);

}
ACE_Task_Base::svc_run (void *args)
{

     ACE_Task_Base *t = (ACE_Task_Base *) args;
     …
     // Call the Task's svc() hook method.
     int svc_status = t->svc ();
     …
}
1.3ACE_Thread_Adapter实现原理
     在说明ACE_Thread_Adapter类的实现原理之前我们首先要明白该类有什么用,被用在哪里。从后缀的Adapter可以猜测该类属于适配器类,而在设计模式中适配器设计模式往往是用来转换接口而用。
1.4 ACE_Thread_Manager实现原理
ACE_Thread_Descriptor类的对象存放程序的描述信息。
ACE_Thread_Manager的实现原理简单概括起来就是:将需要管理的线程的线程信息保存在特定的双向链表中,以供需要操作线程时使用。
将线程加入管理类的方法有两种:
1)使用ACE_Thread_Manager的spawn系列方法启动线程后会自动加入到ACE_Thread_Manager管理的线程双向链表中。
2)直接使用ACE_Thread_Manager的insert_thr方法直接将已启动的线程加入到ACE_Thread_Manager管理的线程双向链表中。
※注释:
不管使用上面那种方法,最终都需要调用append_thr方法将线程信息类ACE_Thread_Descriptor的对象插入到ACE_Double_Linked_List<ACE_Thread_Descriptor> thr_list_信息双向链表中。
使用ACE_Thread_Manager的spawn系列方法最终都会调用spawn_i方法来启动线程,spawn_i方法实现过程中发生了几个关键的调用:
  ACE_Thread::spawn (…)    启动线程
  append_thr(…)       将线程信息插入到双向链表thr_list的尾端。
ACE_Thread_Manager类中对于所管理的线程对象的查找以及操作等都是同过ACE_Thread_Descriptor对象作为参数进行操作的。
    
这里只是简单研究了一下,应该足够用了。可能其中也有些错误之处,请大家指正。
 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值