2013-07-16 2 views
1

여러 스레드를 qt와 동기화하는 데 문제가 있습니다 (불행하게도 3.3.8). 쓰래드를 시작하는 것은 시간 소모적 인 작업이기 때문에, 일단 (작업자) 쓰래드를 한 번 시작하고 실행 방법을 유지하고 새로운 작업에 대해 알리고 싶습니다. 하지만 모든 작업이 완료되면 호출 스레드에서 해당 작업 스레드를 동기화해야합니다.waitconditions를 통해 여러 개의 실행 스레드 대기

QThread의 오버로드가 올바른 사용법이 아니라는 것을 알고 있지만 Qt 3.3.8에는 moveToThread-Method가 없으므로이 작업을 수행해야합니다. 다음

작업자 스레드 클래스가 정의

class WorkerThread : public QThread 
{ 
    private: 
    QWaitCondition m_wcNewWork; 
    QMutex m_mutexStopped; 
    bool m_bStopped; /// Stop thread execution 

    void run() 
    { 
     m_mutexStopped.lock(); 
     while(!m_bStopped) 
     { 
      m_mutexStopped.unlock();  
      m_wcNewWork.wait(); //wait for new work 

      msleep(1000); // do something 

      //>notify main thread that the work is done< 

      m_mutexStopped.lock(); 
     } 
     m_mutexStopped.unlock();  
    } 
    public: 
    WorkerThread() : m_bStopped(false) {} 
    ~WorkerThread() 
    { 
     m_mutexStopped.lock(); 
     m_bStopped = true; 
     m_mutexStopped.unlock();  
     wait(); // Wait for thread 

     //Cleanup  
    } 
    void startProcessing() 
    { 
     m_wcNewWork.wakeOne(); /// Wakeup thread, since there is something to do   
    }   
} 

그 작업자 스레드 무리가 다른 스레드에 생성된다 (단순화). 이것을 하나라고 부르 자 MainThread. 이제 MainThread에 모든 작업자 스레드가 작동 중임을 알릴 내용이 필요합니다. MainThread의 WaitConditions가 모든 WorkerThread에 대해 문제를 해결할 가능성이 있다고 생각했습니다. 그런 다음 MainThread에서 나는이 작업을 수행하는 MainThread을 알리기 위해 waitWorkDone.wakeOne()를 사용하는의 WorkerThread :: 실행-방법에서

QWaitCondition waitWorkDone[numWorker]; 

//Start working 
for (int i = 0; i < numWorker; i++) 
{ 
    WorkerThread[i].setWaitCondition(waitWorkDone); 
    WorkerThread[i].startProcessing(); 
} 

//Wait for all workers to finish their work 
for (int i = 0; i < numWorker; i++) 
{ 
    waitWorkDone[i].wait(); 
} 

같은 것을 썼다. 불행히도 이것은 작동하지 않습니다. 기다리기 전에 waitWorkDone이 깨어 나면 MainThread가 영원히 기다립니다.

그래서 질문은 : 스레드를 동기화 할 수 있습니까? 실행 방법을 벗어나지 않습니다. Qt 4에서는 스레드 풀을 사용하여이 작업을 수행 할 수 있다고 생각하지만 Qt 3에는 존재하지 않습니다.

감사합니다.

답변

0

조건부 변수 (QWaitCondition)를 잘못된 방식으로 사용하고있는 것으로 보입니다. 그들은 뮤텍스를 사용하여 작업을 올바르게 수행해야합니다. 그렇지 않으면 깨어나서 ... 여기와 같이 통화가 끊어 질 수 있습니다. 작업자를 기다리려면 세마포를 사용하거나 쉽게 (쉽게) 할 수 있습니다. 작업자 스레드는 각 스레드를 한 번씩 증가시키고 주 스레드는 numWorker 시간을 감소시킵니다. 당신은 "pthread와 뇌관"책에 조건 변수에 대한 더 나은 설명을 찾아보실 수 있습니다

책-힌트

+0

감사 (멀티 스레딩에 아주 좋은 소개 다소 오래된하지만). 나는 그것을 볼 것이다. 또한 waitcondition :: wait-method의 뮤텍스에 대한 아이디어가 있지만 혼란 스럽습니다. 뮤텍스가 의무적 인 경우, 뮤텍스가 없으면 대기의 목적은 무엇입니까? – AquilaRapax

+0

조건부 변수와 해당 뮤텍스가 함께 작동해야합니다. 뮤텍스는 아무도 해당 조건 변수를 기다리지 않을 때 (잠김 ... 함수가 뮤텍스를 받아들이는 이유입니다.), 아무도 기다리지 않는 조건 변수에서 깨우기를 호출하면 (실제로 발생하는) 뮤텍스가 잠긴 것으로 간주됩니다. –