한국어
Qt
 

C++ Class QThread 소개 및 예제

makersweb 2019.12.25 14:52 조회 수 : 19620

QThread를 이용한 스레드 생성에는 몇가지 방법이 있다. 간단한 예제를 통해서 하나씩 알아본다.

 

worker-object를 QThread객체로 이동(move To Thread)하여 사용하는 방법

 

worker.h

#include <QObject>

class Worker : public QObject
{
    Q_OBJECT
public:
    explicit Worker(QObject *parent = nullptr);
    virtual ~Worker();

public slots:
    void doWork(const QString &);

signals:
    void start(const QString &);
    void resultReady(const QString &result);

};

 

worker.cpp

#include "worker.h"

Worker::Worker(QObject *parent) : QObject(parent)
{

}

Worker::~Worker()
{
    qDebug() << Q_FUNC_INFO;
}

void Worker::doWork(const QString &meter) {
    QString result("hello");

    // 여기서 오래걸리는 작업을 수행

    emit resultReady(result + parameter);
}

 

main.cpp

#include "worker.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QThread thread;

    Worker *worker = new Worker;
    worker->moveToThread(&thread);
    thread.start();

    QObject::connect(worker, &Worker::start, worker, &Worker::doWork);
    QObject::connect(&thread, &QThread::finished, worker, &QObject::deleteLater);

    QObject::connect(worker, &Worker::resultReady, [&](const QString &result){
        qDebug() << result;
        thread.quit(); // 스레드중지
    });

    emit worker->start("World");

    return a.exec();
}

 

QThread를 서브클래싱하여 run() 함수를 다시 구현하는 방법

 

mythread.h

#include <QThread>

class MyThread : public QThread
{
    Q_OBJECT
public:
    MyThread();
    ~MyThread() override;

protected:
    void run() override;
};

 

mythread.cpp

#include <QDebug>
#include "mythread.h"

MyThread::MyThread()
{

}

MyThread::~MyThread()
{
    qDebug() << Q_FUNC_INFO;
}

void MyThread::run()
{
    forever{ // for(;;)와 동일. 무한 루프를 작성하는 데 편의를 제공하는 매크로.

        // 여기서 오래걸리는 코드를 실행

        // 스레드에서 실행 중인 작업을 중지해야 하는 경우 true가 반환됨. 중단은 requestInterruption() 함수로 요청할 수 있다.
        if ( QThread::currentThread()->isInterruptionRequested() ) {
            qDebug() << Q_FUNC_INFO << " terminated";
            return;
        }
    }
}

 

main.cpp

#include "mythread.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    MyThread *thread = new MyThread;
    QObject::connect(thread, &MyThread::finished, thread, &QObject::deleteLater);

    // 스레드 시작
    thread->start();

    QTimer::singleShot(3000, &a, [thread](){

        // 3초후에 스레드 중단을 요청.
        thread->requestInterruption();
    });

    return a.exec();
}

 

create() 정적 메서드를 호출하는 방법

Qt 5.10부터는 create() 정적 메서드를 호출하여 스레드를 생성할 수 있다.

#include <QCoreApplication>
#include <QThread>
#include <QDebug>

void f(){
    forever{

        // 여기서 오래걸리는 작업을 수행

        if ( QThread::currentThread()->isInterruptionRequested() ) {
            return;
        }
    }
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    auto thread = QThread::create(f); // 함수 f를 실행할 새로운 QThread 객체를 만든다.

    thread->start(); // 스레드 시작

    return a.exec();
}

 

 

QThread는 스레드가 시작될 때 started() 를, 중지될 때 finished() 신호를 통해 통지하고 isFinished() 및 isRunning()을 사용하여 스레드 상태를 알 수 있다.

 

스레드를 중지 할 때는 exit() 또는 quit()를 호출한다. 실행중인 스레드를 강제로 종료하는 terminate() 를 호출 할 수 있지만 그런 상황은 되도록이면 없어야한다.

exit() 또는 quit()를 호출한 다음에는 스레드가 실행을 완료 할 때까지 (또는 지정된 시간이 지날 때까지) wait()를 사용하여 호출 스레드를 차단하는 것이 좋다.

 

Qt 4.8부터는 finished() 신호를 QObject::deleteLater()에 연결하여 종료 한 스레드 객체를 안전하게 해제 할 수 있다.

 

또한 플랫폼 독립적인 정적 sleep 함수를 제공한다. sleep(), msleep() 및 usleep()은 각각 초, 밀리초 및 마이크로초를 단위의 함수들이다.

 

Qt는 이벤트 중심(event-driven) 프레임 워크이므로 일반적으로 wait() 및 sleep() 함수는 필요하지 않을 수 있다. wait() 대신 finished() 시그널을 이용하는 것을 고려하자.

번호 제목 글쓴이 날짜 조회 수
공지 Qt프로그래밍(QtQuick) Beginner를 위한 글 읽는 순서 운영자 2019.01.05 86228
19 Qt의 스레드간 시그널 슬롯의 커넥션타입 [1] makersweb 2015.10.24 10226
18 Ubuntu Linux에서 Qt Creator 설치 file makersweb 2016.03.06 10683
17 Qt 응용프로그램 배포(windows) file makersweb 2018.10.10 11397
16 Qt Installer Framework - 패키징, 설치프로그램 제작 file makersweb 2018.10.14 11701
15 QtSerialPort를 사용한 시리얼(Serial)통신 [3] makersweb 2019.05.21 11986
14 Qml 기본 컴포넌트 강좌 (1) file makersweb 2019.01.03 12128
13 Qt의 오픈소스 라이센스 소개 file makersweb 2019.12.15 12639
12 Windows에서 라즈베리파이3용 Qt5.10.0 크로스컴파일 [20] file makersweb 2018.02.23 13060
11 QML과 QtQuick 모듈 개념과 기본 타입들 makersweb 2019.04.26 13443
10 Qml과 C++로 구현하는 GUI어플리케이션 file makersweb 2018.12.25 14031
9 Qt 프로그래밍의 시작 makersweb 2015.10.25 14416
8 초보자를 위한 첫번째 프로젝트 - QML로 만드는 Hello World file makersweb 2018.03.16 14527
7 QtCreator Design으로 GUI만들기 (QML로 만드는 Hello World -2) [1] file makersweb 2019.05.26 14989
» QThread 소개 및 예제 makersweb 2019.12.25 19620
5 Qt의 시그널 슬롯 시스템 file makersweb 2015.10.20 23689
4 Windows에서 Qt 설치 따라하기 file makersweb 2019.10.14 30939
3 QString 문자열 다루기 예제 운영자 2019.01.26 40393
2 콘솔에서 사용자 입력받기 file makersweb 2020.03.22 51864
1 가상키보드(Qt Virtual Keyboard)를 사용하는 방법 [32] file makersweb 2019.05.03 221971