標準C++與線程

來源:互聯網
上載者:User

最初發表在QQ空間:標準C++中實現線程類

 

標準C++和標準庫中沒有對線程的封裝,程式員們不得不使用OS提供的API來處理線程,OS層級的API通常基於C,能用,但並不方便。最近看到論壇上有人問,順便和同事討論這個問題,如何使用標準C++封裝線程的操作,目的就是simple and easy to use。想想自己似乎多年前(已經結蜘蛛網了)寫過這方面的代碼,找了找,還真找到了,是Windows平台的,整理一下,與大家分享。

// 抽象類別,作為線程類的基類,定義了幾個介面// abstract class to provide interface.// class GeneralThread{public: virtual ~GeneralThread() {}public: // create thread and run with specified priority virtual void Run( long priority = THREAD_PRIORITY_BELOW_NORMAL ) = 0; // wait thread running till timeout virtual unsigned long Join( unsigned long ms = INFINITE ) = 0; virtual unsigned long GetExitCode() const = 0; // end thread ingore thread status. virtual void End() {}};typedef GeneralThread     GThread;typedef GThread *      CThreadPtr; // 一個子類,實現了基類的介面,並且定義了一個新的介面來運行真正的線程函數// 因此,可以從這個類繼續派生新的子類,實現自訂的線程函數。// a derived calss from GeneralThread// class SomeThread : public GeneralThread{public: SomeThread() : m_hThread(0) { } ~SomeThread() {  //Join( INFINITE );  if( m_hThread )  {   CloseHandle( m_hThread );   m_hThread = NULL;  } }public: // new interface to implement thread actions virtual unsigned long ThreadProc() = 0;public: virtual void Run( long priority ) {  m_hThread = CreateThread( NULL, 0, &SomeThread::ThreadProc, this, CREATE_SUSPENDED, NULL );  if( m_hThread )  {   SetThreadPriority( m_hThread, priority );   ResumeThread( m_hThread );  }  else  {   DWORD dw = GetLastError();   UNREFERENCED_PARAMETER( dw );  } } virtual unsigned long Join( unsigned long ms ) {  unsigned long ul = WAIT_OBJECT_0;  if( m_hThread )  {   ul = WaitForSingleObject( m_hThread, ms );   switch( ul )   {   case WAIT_OBJECT_0:    //GetExitCodeThread( m_hThread, &m_exitCode );    break;   case WAIT_TIMEOUT:    break;   case WAIT_FAILED:    ul = ul;    break;   }  }  return ul; } virtual unsigned long GetExitCode() const {  DWORD exitCode = 0;  GetExitCodeThread( m_hThread, &exitCode );  return exitCode; } virtual void End() {  TerminateThread( m_hThread, 0xabcd ); }private: static unsigned long WINAPI ThreadProc( LPVOID lpParameter ) {  SomeThread *p = static_cast< SomeThread * >( lpParameter );  return p->ThreadProc(); }private: HANDLE m_hThread;}; // 雖然可以從SomeThread 派生子類,但是如果有多個線程,並且每個線程的線程函數不一樣的話,// 那麼需要實現多個子類,並不是很方便。考慮到標準C++推薦使用模板和函數對象,因此派生了一個// 子類,重新實現了父類中的虛函數,轉寄成對函數對象的訪問。//// if you want to implement your thread, you have to derive a class from SomeThread and also implement your thread procedure.// sometimes you will feel boring.// so here we implement a template class to simplify usage.// thus you don't need to code your derived class, instead just provide your function object.// template< typename F >class ConcreteThread : public SomeThread{public: ConcreteThread( const F &f ) : m_f(f) { }private: unsigned long ThreadProc() {  return m_f(); }private: F m_f;};template< typename F >CThreadPtr MakeThread( F &f ){ return new ConcreteThread< F >( f );} // 這個類提供了另一種形式的封裝。// this class is just for simple usage in  stack scope.// class Thread{public: template< typename F >  Thread( F &f ) : m_pThread( MakeThread(f) ) {  m_pThread->Run(); } ~Thread() {  delete m_pThread; }public: unsigned long Join() {  return m_pThread->Join(); } unsigned long ExitCode() {  return m_pThread->GetExitCode(); }private: CThreadPtr m_pThread;};

代碼不長,而且加了些注釋,不難理解。下面是測試用的代碼

int sum( int end ){ int sum = 0; for( int i = 0 ; i < end ; i++ ) {  sum += i; } return sum;}void TestThread(){ // test Thread class Thread t( std::bind( sum, 10000 ) ), t2( std::bind( sum, 20000 ) ); t.Join(); t2.Join(); std::cout << "sum1 = " << t.ExitCode() << "; sum2 = " << t2.ExitCode() << std::endl; // test ConcreteThread CThreadPtr p = MakeThread( std::bind( sum, 50000 ) ); p->Run(); p->Join(); std::cout << "sum3 = " << p->GetExitCode() << std::endl; //delete p; std::auto_ptr< GeneralThread > p2( MakeThread( std::bind( sum, 50001 ) ) ); p->Run(); p->Join(); std::cout <<"sum4 = " << p->GetExitCode() << std::endl;}

測試代碼很簡短,使用了標準C++的std::bind把sum函數封裝成函數對象,然後在單獨的線程中運行。

一般而言,使用C++封裝系統API以方便使用,通常難度不大,代碼也不會太長。這是一個典型的例子。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.