2013-05-24 3 views
0

내 코드에서 작업자 스레드는 GUI 스레드로 신호를 내 보냅니다. 신호와 슬롯은 Qt :: BlockingQueuedConnection을 통해 연결됩니다.qt 신호 슬롯 다중 스레드 교착 상태

closeEvent 응용 프로그램이 작업자 스레드를 중지하려고 시도하는 중에 이벤트 만 완료하면.

그것은 작업자 스레드의 함수 호출 나아가서는 검사의

void stop() { 
    _isFinished = true; 
    wait(); 
} 

작업자 스레드 _isFinished 조건과이 설정되지 않은 경우, 상기 신호를 방출한다.

분명, 두 스레드가 고정 될 다음과 같은 상황

The worker   Gui Thread 
=================  ================= 
if (!_isFinished)  ----------------- 
-----------------  _isFinished = true; 
-----------------  wait(); 
emit mySignal();  ----------------- 

이미징 - 교착 상태.

뮤텍스를 추가하면 다른 교착 상태가 발생할 수 있습니다. 작업자가 뮤텍스를 잠그면 GUI 스레드가 차단됩니다. 결과적으로 방출 된 신호는 작업자를 잠급니다.

어떻게 처리 할 수 ​​있습니까?

+0

QueuedConnection 대신 BlockingQueuedConnection을 사용하는 특별한 이유가 있습니까? –

+0

예, 신호에 연결된 슬롯이 메모리 개체를 해제해야하기 때문에 중요합니다. 그렇지 않은 경우 메모리 오버플로가 발생합니다. – user14416

답변

0

이것은 상황을 보는 방법입니다.

메인 스레드에서 작업자가 종료 될 때까지 기다릴 필요가 없습니다. 대신 closeEvent은 다음과 같아야합니다

if (workerThread->isRunning()) 
{ 
    workerThread->stop(); 
    event->ignore(); 
} 

이 일을하려면, 당신은 또한, 메인 창을 닫해야 할 때 작업자 스레드 완료 : 마지막으로

connect(workerThread, SIGNAL(finished()), SLOT(close())); 

, 모든 조작과 _isFinished (다른 모든 작업자 스레드의 변수)는 작업자 스레드에서 발생해야합니다. 당신은 간단한 트릭을 달성 할 수있다 :

WorkerThread.h 당신이 교착 상태를 피할 수

public: 
    void stop(); 

protected slots: 
    void p_stop(); 

protected: 
    QMutex mutex; 

WorkerThread.cpp

void WorkerThread::stop() 
{ 
    staticMetaObject.invokeMethod(this, "p_stop", Qt::QueuedConnection); 
} 

void WorkerThread::p_stop(); 
{ 
    QMutexLocker locker(&mutex); 
    _isFinished = true; 
} 

이 방법.

+0

어떤 이유로 'close()'슬롯이 항상 실행되는 것은 아닙니다. 그래서 닫기 버튼을 두 번 (가끔) 눌러야합니다. 그러나 작업자 스레드가 완료됩니다. 어떻게 이런 일이 일어날 수 있니? 왜 '완결 된'신호가 방출되지 않습니까? – user14416

+0

'WorkingThread :: run()'메소드를 질문에 추가 할 수 있습니까? – Amartel