使用ACE_Task管理線程


為什么要使用ACE_Task來管理線程

從C#轉到C++后,感覺到C++比C#最難的地方,就是在系統編程時,C#中有對應的類庫,我接觸到一個類后,就可以通過這個類,知道很多相關的功能。而在C++中,必須使用Windows API,但是Windows API的缺點反而是不系統。比如,想要創建一個線程時,C#中可以通過新建一個Thread類,我得到這個類后,就可以通過幫助或者MSDN了解到這個類中有哪些方法,如何管理線程等。但是C++中,創建一個線程,需要調用CreateThread,但因為它是一個API,所以很難快速的了解到與線程管理相關的API,至少對我來說,這是一個難點。

C#的優勢是以類的方式去管理線程,而C++ 調用API更像是在單打獨斗,顯得特別特別散亂。

那么在C++中,我們能不能以類的方式去管理線程呢。針對這個問題,ACE_Task便浮出了水面。

ACE_Task使用方法

ACE_Task對常用線程處理進行了OO包裝,通過ACE_Task,能對線程進行更好的操作。

根據ACE_Task的父類ACE_Task_Base中的注釋,可以總結出以下幾點:

  • 想要使用ACE_Task,就要從ACE_Task派生一個子類,然后實現比較重要的幾個虛方法。
  • 實現服務初始化和終止方法:open()方法應該包含所有專屬於任務的初始化代碼。其中可能包括諸如連接控制塊、鎖和內存這樣的資源。close() 方法是相應的終止方法。
  • 調用啟用(Activation )方法:在主動對象實例化后,你必須通過調用activate()啟用它。要在主動對象中創建的線程的數目,以及其他一些參數,被傳遞給activate()方法。activate()方法會使svc()方法成為所有它生成的線程的啟動點。
  • 實現服務專有的處理方法:如上面所提到的,在主動對象被啟用后,各個新線程在svc()方法中啟動。應用開發者必須在子類中定義此方法。

實現ACE_Task的虛方法

編寫ACE_Task的Demo

下面就通過總結的幾點來編寫一個Demo

首先是派生ACE_Task的子類ShowTask

#pragma once
#include "ace/Task_T.h"
#include <string>
#include <iostream>
using namespace std;

class ShowTask : public ACE_Task<ACE_SYNCH>
{
public:
  ShowTask(const char* str_to_show, int interval) : show_str_(str_to_show), interval_(interval)
  {
    //啟動線程
    activate();
  }
  ~ShowTask()
  {
    //結束線程
    close();
  }
public:
  virtual int open( void *args = 0 )
  {
    cout << "線程啟動" << endl;
    return 0;
  }

  virtual int close( u_long flags = 0 )
  {
    cout << "線程結束" << endl;
    return 0;
  }

  virtual int svc( void )
  {
    int time_begin = GetTickCount();
    while(true)
    {
      int time_end = GetTickCount();
      if(time_end - time_begin >= interval_)
      {
        time_begin = time_end;
        cout << show_str_ << endl;
      }
      Sleep(10);
    }
    return 0;
  }
private:
  //需要顯示的信息
  string show_str_;
  //間隔多長時間進行顯示
  int interval_;
};

然后在程序中調用ShowTask

#include "ShowTask.h"


int _tmain(int argc, _TCHAR* argv[])
{
    ACE::init();
    string str = "這是一個測試程序";
    ShowTask task(str.c_str(), 1000);

    Sleep(10000);
    ACE::fini();
    return 0;
}

運行效果圖:

demo_運行效果圖

需要注意的地方

在程序中使用ACE_Task,那么就必須在使用前對ACE進行初始化,即調用ACE::init方法,然后在程序結束的時候調用ACE::fini方法。如果沒有進行初始化就調用ShowTask,那么程序就會崩潰。

至於為什么會崩潰,以及ACE::init方法做了些什么,后續的文章中會詳細的介紹。

關於open方法的疑惑

從上面的測試圖中可以看到,線程結束后,調用了close方法,但是在線程啟動時並沒有調用open方法。

而且從谷歌找到的資料中也介紹,在線程啟動的時候回調用open方法,而且他們的示例程序與本文中提供的demo中關於ACE_Task的使用方法也基本一致。

那么open方法為什么沒有被調用呢,究竟是使用方法不對,還是因為ACE版本不同導致的。關於這個問題也會在后續的文章中進行詳細的介紹。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM