2011-09-13 94 views
2

也許有一個非常簡單的解決方案,我的問題,但我真的很困惑與我身邊的所有提升。開始新的線程沒有阻止/等待主要操作

這裏是我的問題:

我要開始一個任務(計算,文件系統操作等),通過調用CallbackReceived功能的回調系統提出的,我想這種操作傳遞給一個線程,通常由對象的成員函數表示。該線程不能保證完成,所以它應該有一些時間後取消它。

喜歡的東西(不知道這是否是100%正確的):

// ... 
MyObject object; 
// ... 
void CallbackReceived(int parameter) { 
    boost::thread tThread(&MyObject::calculate, *&object); 

    boost::asio::deadline_timer tDeadlineTimer(_ioService, boost::posix_time::seconds(2)); 
    tDeadlineTimer.async_wait(boost::bind(DeadlineTimeOut, boost::asio::placeholders::error)); 

    tThread.join(); 
} 

基本上,tThread.join()`的線程的返回等待。在等待期間,我的主人不能收到任何可能因爲被阻止而睡覺的回調。

那麼,在執行操作時,可以運行線程而不是阻止調用初始程序?

+1

...不要調用'join'? ':S' –

+1

你的代碼似乎與你真正做的不一樣,因爲tThread不是像tThread.join()那樣使用它的指針。另外,如果您不想等待線程完成,請不要調用加入。也許未來對你來說是一個更好的工具? – PlasmaHH

+0

@PlasmaHH感謝提示,我錯過了。 – Benjamin

回答

2

你想對計算結果做什麼?

您的主線程在.join()中被阻止。

如果你想處理其他回調,你必須返回到正常執行流程,等待另一個調用。

然後,你必須問自己,當完成計算的結果時你做了什麼。也許這個線程可以把結果放在一個共享資源的某個地方,並且可以優雅地完成。

您必須首先挑選出您的代碼應該執行的所有操作(處理回調,啓動線程,如何處理結果),然後您可以考慮實現它。 boost和C++ 11中有一些新的構造可以適應你,但首先你必須考慮你想要的東西。

+0

你說得對。結果將存儲在某個地方,在這種情況下無關緊要。也許只有打印出來。但是你記得我,那個線程不會總是完成,我忘了記住。所以應該在一段時間後取消。我稍微改變了我的話題,對此造成的不便深表歉意。 – Benjamin

3

當您需要計算結果時,您可以致電join。 類似於「未來」模式。無論如何,你必須讓你的線程變量全局爲CallBackRecieved函數(你可以寫一些包裝)。 注意:你可以調用join,當線程完成它的工作 - 什麼都不會被阻塞。

0

其實你可以在你的主線程正在睡覺時調用回調函數。它只會在線程的上下文(堆棧)上運行。

您可能不想在您所處的位置調用連接,但後來或永遠不會。

例(僞):

class Worker { 

    void doWork(void * mainthread){ 

    Main* main = static_cast<Main*>(mainthread); 

    while(hasWorkTodo){ 
     //work 

     //inform main 
     main->callbackwithinformation(information); 

    } 


} 


class Main{ 

    atomi_int filesfound; 

    void main_part(){ 
    //start worker 
    boost::thread thread(&Worker::doWork, &object, this); 

    while(hasworktodo){ 
     //do work 

     //use filesfound here 
    } 
    //About to finish make sure we join our thread 
    thread.join(); 

    } 

    void callbackwithinformation(int updatedcount){ 
    //here we set a flag or pass some object 
    //probably will need an atomic operation 
    filesfound = updatedcount; 
    } 
} 

你會定義CPP的實現和啊文件,因此沒有循環依賴會出現,因爲你只使用主要是在界面向前參數界面宣言就足夠了。

//worker.h 
class mainthread; 

class Worker {  
    void doWork(void * mainthread); 
} 

//worker.cpp 
#include "main.h" 
void Worker::doWork(/* and so on*/} 


//main.h 
class Main{ 

    atomi_int filesfound; 

    void main_part(); 

    void callbackwithinformation(int updatedcount); 
} 

//main.cpp 
//no need for worker.h here 
void Main::main_part() /* implementation and so on */ 
+0

感謝這個例子。爲什麼join()是如此重要?但是,除此之外,WorkerMain由不同的.h類文件定義。但是,正如我們所知,它們不能包含它們。你有什麼提示嗎? – Benjamin