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 thr_list_信息雙向鏈表中。
使用ACE_Thread_Manager的spawn系列方法最終都會調用spawn_i方法來啓動線程,spawn_i方法實現過程中發生了幾個關鍵的調用:
  ACE_Thread::spawn (…)    啓動線程
  append_thr(…)       將線程信息插入到雙向鏈表thr_list的尾端。
ACE_Thread_Manager類中對於所管理的線程對象的查找以及操作等都是同過ACE_Thread_Descriptor對象作爲參數進行操作的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章