マルチスレッド環境でのシグナルとスロット
1. QThreadクラスのシグナル/スロット機能
QThreadクラスはQObjectを継承しているため、シグナルの発信とスロット関数の定義が可能です。
主要なシグナル
started()- スレッドの実行開始時に発信finished()- スレッドの正常終了時に発信terminated()- スレッドの異常終了時に発信
#ifndef THREADWORKER_H
#define THREADWORKER_H
#include <QThread>
class ThreadWorker : public QThread
{
Q_OBJECT
public:
explicit ThreadWorker(QObject* parent = nullptr);
void execute() override;
signals:
void workCompleted();
private slots:
void handleWork();
};
#endif // THREADWORKER_H
ThreadWorker.h
#include "ThreadWorker.h"
#include <QDebug>
ThreadWorker::ThreadWorker(QObject* parent) : QThread(parent)
{
connect(this, &ThreadWorker::workCompleted,
this, &ThreadWorker::handleWork);
}
void ThreadWorker::handleWork()
{
qDebug() << "Work handling in thread:" << QThread::currentThreadId();
}
void ThreadWorker::execute()
{
qDebug() << "Thread execution started";
for(int count = 0; count < 5; count++)
{
qDebug() << "Processing iteration:" << count;
QThread::sleep(2);
}
emit workCompleted();
qDebug() << "Thread execution completed";
}
ThreadWorker.cpp
#ifndef EVENTHANDLER_H
#define EVENTHANDLER_H
#include <QObject>
class EventHandler : public QObject
{
Q_OBJECT
public:
explicit EventHandler(QObject* parent = nullptr);
private slots:
void onThreadStart();
void onThreadFinish();
void onThreadTerminate();
};
#endif // EVENTHANDLER_H
EventHandler.h
#include "EventHandler.h"
#include <QDebug>
EventHandler::EventHandler(QObject* parent) : QObject(parent) {}
void EventHandler::onThreadStart()
{
qDebug() << "Thread start event handled";
}
void EventHandler::onThreadFinish()
{
qDebug() << "Thread finish event handled";
}
void EventHandler::onThreadTerminate()
{
qDebug() << "Thread termination event handled";
}
EventHandler.cpp
#include <QCoreApplication>
#include "ThreadWorker.h"
#include "EventHandler.h"
int main(int argc, char* argv[])
{
QCoreApplication app(argc, argv);
ThreadWorker worker;
EventHandler handler;
QObject::connect(&worker, &ThreadWorker::started,
&handler, &EventHandler::onThreadStart);
QObject::connect(&worker, &ThreadWorker::finished,
&handler, &EventHandler::onThreadFinish);
QObject::connect(&worker, &ThreadWorker::terminated,
&handler, &EventHandler::onThreadTerminate);
worker.start();
return app.exec();
}
main.cpp
2. スレッド実行モデルの基礎
スタック空間の概念
各スレッドは独立したスタック空間を持ち、関数呼び出し時のパラメータやローカル変数の格納に使用されます。
スレッド安全性
クリティカルリソースにアクセスしない関数は、複数のスレッドから同時に呼び出されても副作用が発生しません。各スレッドが独自のスタック空間を使用するためです。
スレッド識別子
- プロセスはシステム内で一意のPIDを持つ
- スレッドはプロセス内で一意のTIDを持つ
QThreadの静的メンバ関数
QThread* currentThread()- 現在のスレッドオブジェクトを取得Qt::HANDLE currentThreadId()- 現在のスレッドIDを取得