2016-08-17 110 views
0

我作出更大的計劃,我想使首先我試圖找出如何線程實際工作,所以我創建了一個簡單的程序來使用線程,我不明白爲什麼我沒有得到消息比"The bomb has just detonated.""Bomberman has just put a bomb. Wait for the boom."更早。C++線程無法正常工作?

任何人都可以指導我,爲什麼它不按我期望的那樣工作?

#include <unistd.h> 
#include <chrono> 
#include <iostream> 
#include <thread> 

using namespace std; 

class CBomberman; 

class CBomb { 
public: 
    CBomb(void) : m_Owner(nullptr) { 
    thread other_thread(&CBomb::Timer, this); 
    other_thread.join(); 
    } 

private: 
    void Timer(void) { 
    this_thread::sleep_for(chrono::seconds(3)); 
    cout << "The bomb has just detonated." << endl; 
    } 

    CBomberman* m_Owner; 
}; 

class CBomberman { 
public: 
    CBomberman(void) : m_Bomb(nullptr) {} 

    bool PutBomb(void) { 
    if (m_Bomb == nullptr) { 
     m_Bomb = new CBomb(); 
     delete m_Bomb; 
     return true; 
    } else { 
     cout << "The bomb has already been put." << endl; 
     return false; 
    } 
    } 

private: 
    CBomb* m_Bomb; 
}; 

int main() { 
    CBomberman bomberman; 

    bomberman.PutBomb(); 
    cout << "Bomberman has just put a bomb. Wait for the boom." << endl; 

    return 0; 
} 
+0

請修復您發佈的代碼的格式。 – PaulMcKenzie

+0

@PaulMcKenzie我不知道你在說什麼。 – scarface

+0

爲什麼函數聲明中所有額外的空白? – PaulMcKenzie

回答

4

你的問題是,你要加入線程創建後立即,這意味着你只使用多線程在一個非常技術性的感覺:你肯定創建另一個線程,它的(可能)會工作在另一個CPU內核上,但主機線程只是在另一個線程工作時閒置。

您需要在本地存儲thread對象,以便您可以在以後加入。

class CBomb 
{ 
public: 
    CBomb (void) 
    : m_Owner (nullptr), 
    bomb_thread(&CBomb::Timer, this) 
    { 
    } 
    std::thread bomb_thread; //This needs to be a member of this object. Whether you make it public or not is a matter of your design approach. 
private: 
    void Timer (void) 
    { 
     this_thread::sleep_for(chrono::seconds(3)); 
     cout << "The bomb has just detonated." << endl; 
    } 

    CBomberman * m_Owner; 
}; 

class CBomberman 
{ 
public: 
    CBomberman (void) 
    : m_Bomb (nullptr) 
    { 

    } 

    bool PutBomb (void) 
    { 
     if(m_Bomb == nullptr) 
     { 
      m_Bomb = new CBomb();//Don't delete the object immediately after creating it. What were you expecting to have happen if you did? 
      return true; 
     } 
     else 
     { 
      cout << "The bomb has already been put." << endl; 
      return false; 
     } 
    } 
    CBomb * m_Bomb; 
}; 

int main() 
{ 
    CBomberman bomberman; 

    bomberman.PutBomb(); 
    cout << "Bomberman has just put a bomb. Wait for the boom." << endl; 
    bomberman.m_bomb->bomb_thread.join(); //If we hit the end before the thread concludes, there could be some errors. 

    return 0; 
} 
+0

男人,完美!非常感謝你! – scarface

+0

嗯,但它真的很奇怪,當我用它的方式與我在這裏使用它在更大的程序中相同的方式,編譯失敗,錯誤:錯誤:沒有類型命名'類'在類std :: result_of <無效*(CBomb *))()>'' – scarface

+0

@lofofon這聽起來像一個不同的,可能不相關的錯誤。用您的新錯誤發佈一個新問題。還要確保你更新了訪問修飾符:我的代碼將你的一些東西從'private'移動到'public',以使代碼更容易編寫。 – Xirema

0

因爲你創造other_thread後,立即致電other_threadjoinjoin調用會阻塞主線程,並等待other_thread退出。有關std :: thread :: join的文檔,請參見http://en.cppreference.com/w/cpp/thread/thread/join

+0

你能告訴我如何在'int main()'中用'bomberman'調用'thread other_thread'。 PutBomb()''不做'PutBomb()''靜態'? – scarface

+1

將您的線程存儲在本地。並加入main()函數。您可以公開它或創建getter。 – malchemist