2017-01-18 41 views
2

在函數對象的構造函數中通過引用引用的線程對象來引用取消引用的this指針來創建線程是好還是壞?在函數對象構造函數中通過引用由線程對象傳遞引用的this指針來創建線程是好還是壞?

  1. 下面的代碼有什麼問題嗎?
  2. 可以通過改進來達到以下目標嗎?

目標是在類對象超出範圍時正常結束線程。

#include <iostream> 
#include <chrono> 
#include <future> 
#include <thread> 

class MyThread { 
private: 
    std::atomic<bool> exit; 
    std::thread t; 
public: 
    MyThread() : exit(false) { 
     t = std::thread(std::ref(*this)); 
    } 
    ~MyThread() { 
     exit.store(true, std::memory_order_relaxed); 
     if (t.joinable()) { 
      t.join(); 
     } 
    } 
    void operator()() { 
     while (!exit.load(std::memory_order_relaxed)) { 
      std::cout << "."; // some more meaningful work here 
      std::this_thread::sleep_for(std::chrono::seconds(1)); 
     } 
    } 
}; 

int main() { 
    MyThread t; 
    std::cin.get(); 
    return 0; 
} 

回答

4

它可能偶爾工作,但它是不安全的。它可能會產生競爭條件,因爲您在尚未完成構建的對象上啓動線程,導致未定義的行爲。

+3

具體而言,如果在構造函數中引發異常,這是非常危險的。 – Frank

+1

@Frank這確實是一個重要的案例,但我認爲還有其他的情況,足以將該模式歸類爲不安全的。 –

+0

@ A.S.H您是否可以解釋爲什麼在構造中的對象上啓動線程會導致未定義的行爲?競賽狀況在哪裏? – etoricky

相關問題