QThread 상속으로 쓰레드를 생성하지않고 QObject의 moveToThread 함수로 쓰레드를 생성할때 QThread의 wait 함수를 사용하면 무한 블러킹에 걸린다.
이때
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
와 같은 방법으로 worker 에서 finished 를 emit 하고 thread 가 받아서 quit 하게 하여도 마찬가지로 wait 에서는 무한 블러킹에 걸린다
방법은 오직 thread->exit() 과 같이 QThread의 exit 함수를 호출하는 방법 밖에 없었다.
따라서 다음과 같이 구현하면 Worker 쓰레드가 종료할때까지 wait 할 수 있다.
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QThread>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QThread *thread);
virtual ~Worker();
public slots:
void doWork();
private:
QThread* m_pThread;
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_btnStart_clicked();
void on_btnWait_clicked();
private:
Ui::MainWindow *ui;
QThread* m_pThread;
Worker* m_pWorker;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"#include "ui_mainwindow.h"Worker::Worker(QThread *thread){m_pThread = thread;}Worker::~Worker(){}void Worker::doWork(){int count = 0;while (count++ < 10) {printf("do work\n");QThread::sleep(1);}
m_pThread->exit(); // 인수로 받은 QThread의 exit을 호출해야 함}MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow){ui->setupUi(this);m_pThread = new QThread();m_pWorker = new Worker(m_pThread);m_pWorker->moveToThread(m_pThread);connect(m_pThread, SIGNAL(started()), m_pWorker, SLOT(doWork()));}MainWindow::~MainWindow(){delete m_pThread;delete m_pWorker;delete ui;}void MainWindow::on_btnStart_clicked(){if (m_pThread->isRunning()) {return;}
m_pThread->start();}void MainWindow::on_btnWait_clicked(){printf("wait start\n");m_pThread->wait();printf("wait finished\n");}위와 같이 Worker는 QThread를 인수로 받아서 쓰레드 종료시 exit() 을 호출하면 wait() 함수에서종료시점에 동기화를 맞출수 있다
댓글 없음:
댓글 쓰기