2010-05-26 4 views
1

Qt4를 사용하여 멀티 스레드 환경을 구현하고 싶습니다.멀티 스레딩 환경 구현

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()가 실행중인 모든 스레드를 죽이는 것을, 그 변경 내용을 커밋하고 다시 시작 : 모두 의사 코드 - C++에서 다음과 같이 좋습니다. 이 메서드를 시작한 후에는 "abort"를 호출 한 다음 모든 스레드가 종료 될 때까지 대기합니다. 잘못된 방법으로 뮤텍스를 사용 :이 실제로에서라도에서 Qt를 작동

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(); 
    } 

을 아직 문서 mutex2에 따라 동일한 스레드에서 잠금을 해제해야합니다 (및 Windows에서 오류가 발생합니다). 경쟁 조건과 교착 상태에 빠지지 않고 내 목표를 달성하는 가장 좋은 방법은 무엇입니까? 내가 제안한 디자인보다 더 좋은 디자인이 있습니까?

답변

2

이 상황에서는 뮤텍스 대신 조건 변수를 사용하는 것이 좋습니다. 조건 변수는 한 스레드가 다른 스레드에 신호를 보내는 방법입니다. QT의 구현은 QTWaitCondition 인 것으로 보입니다.

나는 자식 스레드가 주기적으로 조건 변수의 상태를 점검하도록 할 수 있습니다. 짧은/0 시간 초과로 QTWaitCondition :: wait()를 사용하여이 작업을 수행 할 수 있습니다. 신호가 보내지는 경우 업데이트 된 데이터가 포함 된 공유 메모리 영역을 잠그고 업데이트해야하는 데이터에 액세스하십시오. 그러면 해당 스레드가 안전하게 다시 시작될 수 있습니다.

일반적으로 스레드를 중단하는 것은 좋지 않습니다. 결국 메모리/리소스/핸들/잠금/누수가 발생할 수 있습니다. 그 스레드가 호출 스택에 어디에 있는지 알 수 없으며 스택이 "unwound"되고 모든 소멸자가 호출된다는 보장이 없을 수도 있습니다. 이것은 하위 스레드가 갱신 된 데이터에 대해 주기적으로 조건 변수를 점검하고 새 데이터로 안전하게 다시 시작하게하는 또 다른 이유입니다.

+0

QWaitConditions에 대한 힌트를 제공해 주셔서 감사합니다. – Searles