2017-10-26 131 views
1

단추를 통해 중지하려고하는 작업자 스레드가 있습니다. 때로 다음 오류가 발생합니다.Qt GUI에서 작업자 스레드 루프를 중지하십시오. 스레드

Fatal: QThread: Destroyed while thread is still running 

여기 내 코드입니다. 연결 해제 단추를 누르면 스레드의 while 루프를 중지하기위한 신호가 방출됩니다.

if (ui->connectButton->text() == "Connect") { 
    mUDPThread = new QThread; 
    mUDPWorker = new UDPThread(ui->HostTextEdit->toPlainText(), ui->portTextEdit->toPlainText().toInt()); 
    mUDPWorker->moveToThread(mUDPThread); 
    connect(mUDPThread, SIGNAL(started()), mUDPWorker, SLOT(process())); 
    connect(mUDPWorker, SIGNAL(finished()), mUDPThread, SLOT(quit())); 
    connect(mUDPWorker, SIGNAL(finished()), mUDPWorker, SLOT(deleteLater())); 
    connect(mUDPWorker, SIGNAL(finished()), mUDPThread, SLOT(deleteLater())); 
    connect(this, SIGNAL(onExitThread()), mUDPWorker, SLOT(onExitThread())); 
    connect(this, SIGNAL(onDataIncome(QString)), mUDPWorker, SLOT(onDataIncome(QString))); 
    mUDPThread->start(); 
    ui->connectButton->setText("Disconnect"); 
} else if (ui->connectButton->text() == "Disconnect") { 
    emit onExitThread(); 
    ui->connectButton->setText("Connect"); 
} 

작업자 스레드 :

void UDPThread::process() { 
    while (isRunning) { 
    QCoreApplication::processEvents(); 
     ... 
    } 
    emit finished(); 
} 
void UDPThread::onExitThread() { 
    qDebug() << "onExitThread" << isRunning; 
    isRunning = false; 
} 

답변

0

해결되었습니다. 이 오류는 연결 명령 이내 :

connect(mUDPWorker, SIGNAL(finished()), mUDPThread, SLOT(deleteLater())); 

connect(mUDPThread, SIGNAL(finished()), mUDPThread, SLOT(deleteLater())); 

에 결과 :

connect(mUDPThread, SIGNAL(started()), mUDPWorker, SLOT(process())); 
connect(mUDPWorker, SIGNAL(finished()), mUDPThread, SLOT(quit())); 
connect(mUDPWorker, SIGNAL(finished()), mUDPWorker, SLOT(deleteLater())); 
connect(mUDPThread, SIGNAL(finished()), mUDPThread, SLOT(deleteLater())); 
connect(this, SIGNAL(onExitThread()), mUDPWorker, SLOT(onExitThread())); 
connect(this, SIGNAL(onDataIncome(QString)), mUDPWorker, SLOT(onDataIncome(QString))); 
2

while (isRunning)

당신은 거기 스레드를 차단하고, 자사의 이벤트 루프는 단지 다른 스레드에 신호를 보낼 수 신호를 수신하기 위해 회전 수 없습니다 회전 이벤트 루프와 함께.

작업자를 비 블로킹으로 만들고 작업 루프를 작업 루프로 분할해야하며 이벤트 루프 사이에서 신호를 수신하고 신호를 수신해야합니다. 의사 코드에서 :

if (isRunning) { 
    doWorkCycle(); 
    scheduleNextWorkCycle(); 
} else emit finished(); 

here 볼 수 있습니다 예를 들어 있습니다.

+0

미안 해요, 난 processEvents()를 호출 물론) (완료 방출한다. 내가 질문을 업데이 트 – momosxp

+0

@ momosxp 나는 그것이 도움이된다고 생각하지 않는다. 스레드가 차단되었으므로 처리 할 수있는 어떤 이벤트도받지 못한다. 그것이 작동 할지라도,'processEvents()'를 수동으로 호출해야하는 것은 잘못된 디자인을 나타냅니다. 도움을 주신 덕분에 – dtech

+0

. invokemethod를 사용하는 링크에 따라 구현하려고했습니다. ProcessEvents를 사용하지 않고 작동하지만 여전히 동일한 오류 메시지로 인해 충돌하는 경우가 있습니다. – momosxp