2010-05-26 175 views
1

我想使用Qt4實現多線程環境。我們的想法是在C++如下 - 一樣的僞代碼:實現多線程環境

class Thread : public QThread { 
    QList<SubThread*> threads_; 

public: 
    void run() { 
     foreach(SubThread* thread : threads) { 
      thread.start(); 
     } 

     foreach(SubThread* thread : threads) { 
      thread.wait(); 
     } 
    } 

    void abort() { 
     foreach(SubThread* thread : threads) { 
      thread.cancel(); 
     } 
    } 

public slots: 
    // This method is called from the main-thread 
    // (sometimes via some signal-slot-connection) 
    void changeSomeSettings() { 
     abort(); 
     // change settings 
     start(); 
    } 
} 

class SubThread : public QThread { 
    bool isCancelled_; 

public: 
    void run() { 
     while(!isCancelled or task completed) { 
      // something that takes some time... 
     } 
    } 

    void cancel() { 
     if(isRunning() { 
      isCancelled_ = true; 
     } 
    } 
} 

的目的是,所述槽changeSomeSettings()殺死所有正在運行的線程,其提交更改和重新啓動它。我想要實現的是,一旦這個方法已經啓動,它會調用「中止」,然後等到所有線程都終止。以錯誤的方式使用互斥:

void Thread::changeSomeSettings() { 
     mutex1.lock(); 
     abort(); 

     mutex2.lock(); 

     start(); 
     mutex1.unlock(); 
    } 

    void Thread::run() { 
     foreach(Thread* thread : threads) { 
      thread.start(); 
     } 

     foreach(Thread* thread : threads) { 
      thread.wait(); 
     } 

     mutex2.unlock(); 
    } 

這實際工作中的Qt的MacOSX下,但根據文檔互斥鎖2,必須在同一個線程解鎖(和Windows我得到一個錯誤)。在不遇到賽車條件和僵局的情況下達成目標的最佳方式是什麼?有沒有比我在這裏提出的更好的設計?

回答

2

對於這種情況,您可能希望使用條件變量而不是互斥鎖。條件變量是一個線程發送另一個線程的方式。 QT的實現似乎是QTWaitCondition

我可能讓子線程定​​期檢查條件變量的狀態。這可以通過使用QTWaitCondition :: wait()以及一個短/ 0超時來完成。如果正在發送信號,則鎖定包含更新數據的共享內存區域並訪問需要更新的數據。然後該線程可以相應地安全地重啓自身。

只是放棄一個線程通常不是一個好主意。你可能會泄漏內存/資源/句柄/鎖/等。你不知道該線程在調用堆棧中的位置,並且可能無法保證堆棧將被「解開」並且所有析構函數都被調用。這是子線程定期檢查一個條件變量以獲取更新數據的另一個原因,並讓他們使用新數據安全地重新啓動。

+0

感謝提供QWaitConditions的提示。 – Searles 2010-05-26 15:32:12