2012-11-10 42 views
3

我想寫一個類,它將在其對象創建時運行一個線程,並在對象被刪除後停止線程。刪除boost ::線程後裔

class MyThread : public boost::thread { 

public: 

    MyThread() : bAlive(true) { 
     boost::thread(&MyThread::ThreadFunction,this); 
    } 

    ~MyThread() { 
     { 
      boost::unique_lock<boost::mutex> lock(Mutex); 
      bAlive=false; 
     } 
     ConditionVariable.notify_one(); 
     join(); 
    } 

private: 

    volatile bool bAlive; 
    boost::mutex Mutex; 
    boost::condition_variable ConditionVariable; 

    void ThreadFunction() { 
     boost::unique_lock<boost::mutex> lock(Mutex); 
     while(bAlive) { 
      ConditionVariable.timed_wait(lock,boost::get_system_time()+ boost::posix_time::milliseconds(MAX_IDLE)); 

      /******************************************* 
      * Here goes some code executed by a thread * 
      *******************************************/ 

     } 
    } 

}; 

從理論上講,我想馬上儘快喚醒線程了,因爲它需要完成,所以我只好用TIMED_WAIT而不是睡眠。 這工作正常,直到我嘗試刪除此類的一個對象。在大多數情況下,它會正常刪除,但偶爾它會在condition_variable.hpp,thread_primitives.hpp或crtexe.c中導致錯誤。有時我會收到通知:「釋放後在3da804中修改了自由堆3da7a8」,有時候我沒有。是的,我知道timed_wait的虛假喚醒,在這種情況下並不重要。 你能指點我的問題來源嗎?我究竟做錯了什麼?

+0

不太清楚的問題是什麼,有沒有問號在這個問題 – jcw

回答

1

我看到你想要做什麼,但是當你想到它不起作用:

MyThread foo; 

默認構造一個boost ::線程(因爲MyThread的是自boost ::線程派生)。 默認構造函數創建一個引用Not-a-Thread的boost :: thread實例。

MyThread() { 
    boost::thread(&MyThread::ThreadFunction,this); 
} 

實際上是創建一個不同的線程,你忽略了返回的對象(有效的線程)。然後

~MyThread() { 
    // ... 
    join(); 
} 

試圖加入到默認的構造線程(拋出一個異常析構函數內),你永遠不會加入,實際上做的工作線程。


首先,不要從boost :: thread派生。創建一個成員變量來代替:

class MyThread { 
// ... 
private: 
    // ... 
    boost::thread _thread; 
}; 

在構造函數中,創建和線程分配給成員變量:

MyThread() { 
    _thread = boost::thread(&MyThread::ThreadFunction,this); 
} 

,並調用其join()方法在你的析構函數。

~MyThread() { 
    // ... 
    _thread.join(); 
} 

這應該可以解決您的問題。


但是,如果你只是想退出時,你的對象被銷燬(並沒有將其喚醒,而它的運行)的線程,你可以使用不同的方法。取消互斥和條件變量並改爲使用中斷。這將導致睡眠()拋出一個異常,所以你必須抓住它:

void ThreadFunction() { 
    try { 
     for(;;) { 
      boost::this_thread::sleep(boost::posix_time::milliseconds(MAX_IDLE)); 
      // Here goes some code executed by a thread 
     } 
    } catch(const boost::thread_interrupted& e) { 
     // ignore exception: thread interrupted, exit function 
    } 
} 

當線程被中斷,這將立即退出ThreadFunction。如果您不需要線程在每個循環中休眠,則可以用boost::this_thread::interruption_point()替換它。如果線程中斷,這隻會引發異常。

現在,你可以簡單地中斷線程在析構函數:

MyThread::~MyThread() { 
    _thread.interrupt(); 
    _thread.join(); 
} 
+0

謝謝你很多!這已經幫助解決了我的問題。 – user1814683