서론
QT에서의 Thread를 공식문서와 함께 알아보자
https://doc.qt.io/qt-6/qthread.html#protected-functions
Public Function
반환형 | 메서드 | 설명 |
QThread(QObject *parent = nullptr) | QThread 객체를 생성, 선택적으로 부모 QObject 설정가능 | |
virtual | ~QThread() | QThread 객체를 소멸, 소멸자가 호출될 때 스레드가 종료되지 않았으면 스레드를 종료 |
QAbstractEventDispatcher * | eventDispatcher() const | 현재 스레드의 이벤트 디스패처를 반환 이벤트 디스패처는 이벤트 루프에서 이벤트를 처리하는 역할을 한다. |
bool | isFinished() const | 스레드가 종료되었는지 여부를 반환한다. 성공적으로 완료된 경우 true를 반환 |
bool | isInterruptionRequested() const | 스레드 중단 요청이 있었는지 여부를 반환한다. requestInterruption() 함수가 호출된 경우 true를 반환 |
bool | isRunning() const | 스레드가 현재 실행 중인지 여부를 반환한다. 실행 중이면 true |
int | loopLevel() const | 현재 스레드의 이벤트 루프 중첩 레벨을 반환한다. 이벤트 루프가 중첩된 수준을 나타낸다. |
QThread::Priority | priority() const | 스레드의 우선순의를 반환한다. 우선순의눈 QThread::Priority 열거형에 의해 정의된다. |
void | requestInterruption() | 스레드에 중단을 요청한다. 스레드가 주기적으로 isInterruptionRequested()를 체크하여 중단 요청을 확인하도록 해야 한다. |
void | setEventDispatcher(QAbstractEventDispatcher *eventDispatcher) | 스레드의 이벤트 디스패처를 설정한다. |
void | setPriority(QThread::Priority priority) | 스레드의 우선순의를 설정한다. QThread::Priority 열거형에 의해 정의된다. |
void | setStackSize(uint stackSize) | 스레드의 스택 크기를 설정한다. 스레드가 사용할 스택 메모리의 크기를 지정한다. |
uint | stackSize() const | 스레드의 스택 크기를 반환한다. |
bool | wait(QDeadlineTimer deadline = QDeadlineTimer(QDeadlineTimer::Forever)) | 지정된 QDeadlineTimer까지 스레드가 종료될 때까지 대기한다. 기본값으로는 무한정 대기 |
bool | wait(unsigned long time) | 지정된 시간(밀리초) 동안 스레드가 종료될 때까지 대기한다. 지정된 시간이 지나면 false, 종료되면 true를 반환한다. |
enum QThread::Priority
예제 코드
////////[mythread.cpp]/////////
#include "mythread.h"
MyThread::MyThread(QObject *parent) : QThread(parent) {
}
void MyThread::run() {
qDebug() << "쓰레드 시작";
while(!isInterruptionRequested()){
QThread::sleep(1);
qDebug() << "쓰레드가 작동중입니다.";
}
qDebug() << "쓰레드가 종료 중입니다.";
}
////////[main.cpp]///////////
#include <QCoreApplication>
#include <QDebug>
#include <QDeadlineTimer>
#include <QEventLoop>
#include "mythread.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MyThread thread;
QObject::connect(&thread, &QThread::finished, [](){
qDebug() << "쓰레드가 종료되었습니다.";
});
// Start Thread
thread.start();
qDebug() << "쓰레드가 작동중입니다." << thread.isRunning();
// Set Thread Priority
thread.setPriority(QThread::HighPriority);
qDebug() << "쓰레드 우선 순위 : " << thread.priority();
// Set Stack Szie
thread.setStackSize(1024 * 1024); // 1 MB
qDebug() << "쓰레드 스택 사이즈 : " << thread.stackSize();
// Request interruption
QThread::sleep(3); // Let the thread run for a while
thread.requestInterruption();
qDebug() << "중단 요청 : " << thread.isInterruptionRequested();
// Wait for the thread to finish
if (thread.wait(QDeadlineTimer(QDeadlineTimer::Forever))) {
qDebug() << "스레드가 데드라인에 의한 종료";
} else {
qDebug() << "스레드가 데드라인까지 종료되지 못함";
}
qDebug() << "쓰레드가 종료된 상태 :" << thread.isFinished();
return a.exec();
}
Public Slots
반환형 | 메서드 | 설명 |
void | exit() | 스레드의 실행을 종료하고, run() 메서드가 종료된다. |
void | quit() | 스레드의 이벤트 루프를 종료한다. QThread를 사용하는 경우 run 메서드 안에서 이벤트 루프가 실행될 때, quit()을 호출하면 루프가 종료된다. 종료 후에는 exec()가 호출된다. |
void | start() | 스레드를 시작한다. 선택적으로 priority를 지정하여 스레드의 우선순위를 설정한다. |
void | terminate() | 스레드를 강제로 종료한다. 스레드가 terminate() 슬롯을 호출하면, 스레드는 즉시 종료되고, 현재 실행 중인 run() 메서드가 중단된다. |
exit()와 quit()의 차이
- quit()
- 이벤트 루프가 실행 중인 경우, 현재 처리 중인 이벤트를 모두 처리한 후 이벤트 루프를 종료한다.
- 종료 후에는 exec() 호출이 반환된다.
- 일반적으로 이벤트 루프를 정상적으로 종료하고 싶을 때 사용된다.
- exit()
- 이벤트 루프가 종료되면 exec()가 반환되고, 이 반환 값은 returnCode가 된다.
- quit()와 비슷하게 이벤트 루프를 종료하지만, 종료 시 특정 반환 값을 설정할 수 있다.
- 기본 반환 값은 0이며, 이는 일반적으로 성공을 의미한다.
Signals
반환형 | 메서드 | 설명 | 용도 |
void | finished() | 스레드가 실행을 마치고 종료되었을 때 발생하는 시그널이다. 스레드의 run() 메서드가 완료되거나 스레드가 exit(), quit() 호출로 종료되면 이 시그널이 방출된다. |
스레드가 완료된 후에 후처리를 수행하거나, 스레드 종료를 기다리는 다른 작업을 수행하는 데 사용된다. |
void | started() | 스레드가 시작됐을 때 발생하는 시그널이다. start() 메서드가 호출되어 스레드의 run() 메서드가 실행되기 시작할 때 이 시그널이 방출된다. | 스레드가 실행을 시작할 때, 초기화 작업이나 로그 기록을 할 때 사용된다. 스레드가 실행 중임을 알리는 데 유용하다. |
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MyThread *thread = new MyThread();
QObject::connect(thread, &QThread::started, []() {
qDebug() << "Thread has started";
});
QObject::connect(thread, &QThread::finished, []() {
qDebug() << "Thread has finished";
});
thread->start();
thread->wait(); // Wait for the thread to finish
delete thread;
return a.exec();
}
Static Public Members
static public 멤버들은 스레드 관련 작업을 수행하거나 정보를 얻는데 사용된다.
이 함수들은 특정 QThread 객체의 멤버가 아닌 QThread 클래스 자체의 멤버로 사용된다.
메서드 | 설명 | 예시 |
QThread *create | 새 스레드를 생성한다. | QThread::create( [] () { /* 작업 */ })->start(); |
QThread *currentThread() | 현재 실행 중인 스레드에 대한 QThread 객체 포인터를 반환한다. 이 함수를 통해 현재 스레드의 정보를 얻을 수 있다. |
QThread *current = QThread::currentThread(); |
Qt::HANDLE currentThreadId() | 현재 실행 중인 스레드의 ID를 반환한다. | Qt::HANDLE threadId = QThread::currentThreadId(); |
int idealThreadCount() | 시스템에서 이상적인 스레드 수를 반환 | int threadCount = QThread::idealThreadCount(); |
void msleep(unsigned long msecs) | 현재 스레드를 지정된 밀리초 동안 정지 | QThread::msleep(500); |
void sleep(unsigned long secs) | 현재 스레드를 지정된 초 동안 중지 | QThread::sleep(2); |
void sleep(std::chrono::nanoseconds nsecs) | 현재 스레드를 지정된 나노초 동안 중지 | QThread::sleep(std::chrono::nanoseconds(1000000)); |
void sleep(unsigned long usecs) | 현재 스레드를 지정된 마이크로초 동안 중지 | QThread::usleep(100); |
void yieldCurrentThread() | 현재 실행 중인 스레드가 남은 실행 시간을 다른 스레드에게 양보한다. 이는 스레드 스케줄러에게 현재 스레드의 실행을 중단하고 다른 스레드를 실행시키도록 지시한다. |
QThread::yieldCurrentThread(); |
Protected Functions
int exec()
- 기능 : exec() 함수는 스레드의 이벤트 루프를 실행한다. 스레드가 이벤트 루프를 실행하는 동안, 스레드는 run() 메서드가 호출되기 전까지 블록된다. 이 함수는 주로 스레드 내에서 이벤트 기반 작업을 수행할 때 사용된다.
- 용도 : QThread를 사용하는 경우, exec()를 호출하면 스레드는 이벤트 루프를 시작하고, 이 루프가 종료될 때까지 계속 실행된다 주로 GUI 스레드나 비동기 이벤트 처리가 필요한 경우에 사용된다.
- 리턴값 : 이벤트 루프가 종료되면, exec()는 QEventLoop::exec()와 동일한 방식으로 종료 상태 코드를 반환한다.
void MyThread::run() {
qDebug() << "Thread started";
exec(); // Start the event loop
qDebug() << "Thread finished";
}
예제에서 exec()는 스레드가 이벤트 루프를 시작하도록 하고, 스레드는 이벤트 루프가 종료될 때까지 실행된다.
exec() 호출 이후에 스레드는 run() 메서드를 계속 실행한다.
virtual void run()
- 기능 : run() 함수는 QThread를 상속받아 스레드에서 실행할 코드를 정의하는 가상 함수이다. 이 함수는 스레드가 시작될 때 호출된다.
- 용도 : 스레드에서 실행할 작업을 이 함수에 정의한다. 기본 run() 구현은 아무 작업도 수행하지 않지만, QThread를 상속받은 클래스에서 이 메서드를 재정의하여 스레드의 실제 작업을 정의한다.
class MyThread : public QThread
{
Q_OBJECT
protected:
void run() override {
qDebug() << "Thread started";
QThread::sleep(2); // Simulate some work
qDebug() << "Thread finished";
}
};
예제에서 run() 메서드는 스레드가 실행될 때 호출다.
스레드는 run() 메서드 내의 코드를 실행하고, 작업이 완료되면 스레드는 종료된다.
다음 시간에는 여러 클래스들을 QThread로 효율적인 작업을 하는 코드를 만들어보자
내일은 외근이 있어서 수요일쯤 해야겠다~
'🌠Development > QT' 카테고리의 다른 글
QT - 스레드 동기화(Thread Synchronization) (2) | 2024.07.24 |
---|---|
QT - Thread (3) 2개의 클래스 객체를 스레드로 실행시키기 (1) | 2024.07.24 |
Qt - Thread(1) (1) | 2024.07.22 |
QT project - 메모장 구현하기 (0) | 2024.07.19 |
QT - QFileDialog 사용해보기 (0) | 2024.07.19 |