2014-07-18 81 views
0
struct Foo 
{ 
    boost::thread thread_; 

    void launchThread() 
    { 
     boost::thread(boost::bind(&Foo::worker, this)); 
    } 

    void worker() 
    { 
    ~Foo(); 
    } 

    ~Foo() 
    { 
     if (boost::this_thread::get_id() != thread_.get_id()) 
     thread_.join(); 
    } 

}; 

在C++ 11中,在可聯接線程中調用聲明線程的類的析構函數是合法的嗎?從可連接線程中銷燬線程的對象

EDIT1,更現實的例子:

struct Holder 
{ 
    std::unique_ptr<SocketClient> client_; 
    void ondisconnected(){client_.release();} 
    Holder() 
    { 
     //create SocketClient and launch the thread 
    } 
} 

struct SocketClient 
{ 
    boost::thread thread_; 

    void launchThread() 
    { 
     boost::thread(boost::bind(&SocketClient ::worker, this)); 
    } 

    void worker() 
    { 
     run_ = true; 
     while (run_) 
     { 
      boost::system::error_code error; 

      auto receveidBytesCount = socket_.read_some(boost::asio::buffer(socketBuffer_), error); 

      if (error == boost::asio::error::eof) 
      { 
       disconnected_() // call Holder slot 
       return;   
      } 
     } 
    } 

    ~SocketClient() 
    { 
     run_ = false; 
     socket_.shutdown(boost::asio::socket_base::shutdown_both); 
     socket_.close(); 

     if (boost::this_thread::get_id() == thread_.get_id()) 
      thread_.detach(); 
     else 
      thread_.join(); 
    } 
}; 
+1

爲什麼你要做一個顯式的析構函數?這沒有任何意義。 –

+0

@ T.C。:添加一個更現實的例子來解釋爲什麼我需要這樣做。 – Guillaume07

回答

4

編號A可連接的線程必須加入或thread對象被銷燬之前脫離。如果從該線程調用,這將不會執行。該線程的析構函數將調用terminate(),結束程序。

分離線程是否可接受取決於您是否還銷燬線程訪問的對象。這取決於您的線程交互的大規模設計,並且一般不能真正回答。

請注意,顯式調用這樣的析構函數幾乎肯定無效;我假設這只是爲了說明析構函數在線程中被調用(以更合適的方式)。

+0

感謝您的回答,我添加了更實際的示例 – Guillaume07

+0

實現分配器時,顯式調用析構函數是有效的。還要注意,銷燬一個'std :: thread'對象不會破壞線程函數對象和任何你提供給'std :: thread'構造函數的參數。它們不作爲'std :: thread'對象的數據成員存儲,並在執行線程退出時被銷燬。這種行爲是標準的。 – Lingxi