2009-09-01 115 views
0

除了主線程,我已經ThinkerThread對象_thinker其成品()信號被連接到主線程的槽:問題同步QThreads

connect(&_thinker, SIGNAL(finished()), this, SLOT(autoMove())); 

槽汽車移動()導致_thinker初始化並再次運行:

_thinker.setState(/* set internal variables to run properly */); 
_thinker.start(); 

這樣_thinker可以繼續使用新數據運行,並在autoMove()插槽的主線程中給用戶一些反饋。

問題是當用戶希望爲_thinker加載一個新的狀態(可能來自文件或其他菜單操作)時,我無法同步兩個_thinker狀態。

假設_thinker正在運行,並且用戶從文件加載新的狀態。現在,_thinker完成()時,它會調用autoMove()並顯示反饋。但有可能給用戶錯誤的反饋,因爲可能是從文件加載導致內部狀態改變。這意味着_thinker的內部狀態和主線程的內部狀態不一樣。

  1. _thinker開始,狀態說s0。
  2. 用戶從文件加載另一個狀態,比如說s1。
  3. _thinker完成並執行autoMove()。

因此,在步驟3之後,autoMove()會給出狀態s0的反饋,這是不期望的。我想要做的是在用戶從文件加載新狀態時停止執行_thinker。我認爲我的設計很差,我想知道這種情況下的最佳做法。我的加載函數以與autoMove()相同的方式初始化_thinker,調用相同的函數(還有另一個函數調用_thinker.setState()和start())。

現在我已經做了在負載下()函數:

disconnect(&_thinker, SIGNAL(finished()), this, SLOT(autoMove())); 
_thinker.terminate(); 
_thinker.wait(); 
connect(&_thinker, SIGNAL(finished()), this, SLOT(autoMove())); 

這並不能完全消除的問題,那就是,汽車移動()仍稱並給出了以前的狀態的反饋。我在Windows中使用Qt Creator 1.2.1和Qt 4.5.2版本。

謝謝你的時間。

編輯

這是通常的執行步驟(當負載()不被調用):

_thinker.setState(); 
_thinker.start(); 
//when _thinker finished() 
autoMove(); 
    > _thinker.setState(); 
    > _thinker.start(); 

當負載()被調用:

_thinker.setState(); 
_thinker.start(); 
load(); 
    > _thinker.setState(); 
    > _thinker.start(); 
//when _thinker finished() 
autoMove(); // this is the feedback for previous or current state 
    > _thinker.setState(); 
    > _thinker.start(); 

請注意,load()會導致_thinker重新啓動。現在,在哪裏布爾檢查,以便autoMove()應該忽略只有一次?

回答

1

有關使用如何整數ID來確定哪個狀態已經被計算,看看它在計算完成時是否仍然有效?

0

不完全是最佳實踐,但爲什麼不用bool標記(使用互斥體,如果必須的話)狀態在執行過程中發生了變化,如果是這樣,只需重新啓動autoMove中的線程(不提供任何反饋)。

更新: 我的想法是這樣的:

autoMove() 
{ 
    .... 
    if (!_thinker.stateChanged()) 
    { 
     // provide feedback 
    } 
    //restart _thinker -> on restart _thinker.isStateChanged = false; 

} 

當然,如果用戶改變狀態的時候,你可能永遠達不到的提供反饋支路:P

+0

這是通常的執行步驟(不調用load()時): _thinker.setState(); _thinker.start(); //當_思考完成時() autoMove(); > _thinker.setState(); > _thinker.start(); load()被調用時: _thinker.setState(); _thinker.start(); load(); > _thinker.setState(); > _thinker.start(); //當_思考完成時() autoMove(); //這是以前的反饋 //或當前狀態 > _thinker.setState(); > _thinker.start(); 請注意,load()會導致_thinker重新啓動。現在,在哪裏布爾檢查,以便autoMove()應該忽略只有一次? – Donotalo

+0

哦,格式化分手了。我將其重新發布在原始帖子中。 – Donotalo