Qtマルチスレッドにおけるシグナルとスロットの実装

マルチスレッド環境でのシグナルとスロット

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を取得

タグ: Qt マルチスレッド シグナル スロット qthread

8月2日 04:01 投稿