2014-07-18 62 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