QThread Class

QThread クラスは、プラットフォームに依存しないスレッド管理方法を提供します。詳細...

Header: #include <QThread>
CMake: find_package(Qt6 REQUIRED COMPONENTS Core)
target_link_libraries(mytarget PRIVATE Qt6::Core)
qmake: QT += core
Inherits: QObject

パブリック型

enum Priority { IdlePriority, LowestPriority, LowPriority, NormalPriority, HighPriority, …, InheritPriority }

パブリック関数

QThread(QObject *parent = nullptr)
virtual ~QThread()
QAbstractEventDispatcher *eventDispatcher() const
(since 6.8) bool isCurrentThread() const
bool isFinished() const
bool isInterruptionRequested() const
bool isRunning() const
int loopLevel() const
QThread::Priority priority() const
void requestInterruption()
void setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)
void setPriority(QThread::Priority priority)
void setStackSize(uint stackSize)
uint stackSize() const
bool wait(QDeadlineTimer deadline = QDeadlineTimer(QDeadlineTimer::Forever))
bool wait(unsigned long time)

再実装パブリック関数

virtual bool event(QEvent *event) override

パブリック・スロット

void exit(int returnCode = 0)
void quit()
void start(QThread::Priority priority = InheritPriority)
void terminate()

シグナル

void finished()
void started()

静的パブリックメンバ

QThread *create(Function &&f, Args &&... args)
QThread *currentThread()
Qt::HANDLE currentThreadId()
int idealThreadCount()
(since 6.8) bool isMainThread()
void msleep(unsigned long msecs)
(since 6.6) void sleep(std::chrono::nanoseconds nsecs)
void sleep(unsigned long secs)
void usleep(unsigned long usecs)
void yieldCurrentThread()

保護された関数

int exec()
virtual void run()

静的プロテクトメンバ

void setTerminationEnabled(bool enabled = true)

詳細説明

QThread オブジェクトは、プログラム内の制御の 1 つのスレッドを管理します。QThread はrun() で実行を開始します。デフォルトでは、run() はexec() を呼び出すことでイベントループを開始し、スレッド内部で Qt イベントループを実行します。

QObject::moveToThread() を使用してスレッドに移動することで、ワーカーオブジェクトを使用できます。

class Worker : public QObject
{
    Q_OBJECT

public slots:
    void doWork(const QString &parameter) {
        QString result;
        /* ... here is the expensive or blocking operation ... */
        emit resultReady(result);
    }

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

class Controller : public QObject
{
    Q_OBJECT
    QThread workerThread;
public:
    Controller() {
        Worker *worker = new Worker;
        worker->moveToThread(&workerThread);
        connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
        connect(this, &Controller::operate, worker, &Worker::doWork);
        connect(worker, &Worker::resultReady, this, &Controller::handleResults);
        workerThread.start();
    }
    ~Controller() {
        workerThread.quit();
        workerThread.wait();
    }
public slots:
    void handleResults(const QString &);
signals:
    void operate(const QString &);
};

ワーカースロット内のコードは、別のスレッドで実行されます。しかし、Workerのスロットは、どのスレッドでも、どのオブジェクトからでも、どのシグナルに接続してもかまいません。queued connections と呼ばれるメカニズムのおかげで、異なるスレッド間でシグナルとスロットを安全に接続することができます。

別のスレッドでコードを実行させるもう1つの方法は、QThreadをサブクラス化し、run ()を再実装することです。例えば

class WorkerThread : public QThread
{
    Q_OBJECT
    void run() override {
        QString result;
        /* ... here is the expensive or blocking operation ... */
        emit resultReady(result);
    }
signals:
    void resultReady(const QString &s);
};

void MyObject::startWorkInAThread()
{
    WorkerThread *workerThread = new WorkerThread(this);
    connect(workerThread, &WorkerThread::resultReady, this, &MyObject::handleResults);
    connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
    workerThread->start();
}

この例では、スレッドはrun関数が戻った後に終了します。exec() を呼び出さない限り、スレッド内でイベント・ループが実行されることはありません。

QThreadインスタンスは、run ()を呼び出す新しいスレッドではなく、それをインスタンス化した古いスレッドlives in 。これは、QThreadのキューイングされたスロットとinvoked methods のすべてが古いスレッドで実行されることを意味します。従って、新しいスレッドでスロットを呼び出したい開発者は、ワーカーオブジェクトアプローチを使用する必要があります。

キューに入れられたスロットや呼び出されたメソッドとは異なり、QThread オブジェクト上で直接呼び出されたメソッドは、そのメソッドを呼び出したスレッドで実行されます。QThread をサブクラス化する場合、コンストラクタは古いスレッドで実行され、run() は新しいスレッドで実行されることに注意してください。メンバ変数が両方の関数からアクセスされる場合、その変数は2つの異なるスレッドからアクセスされることになります。そうすることが安全であることを確認してください。

注意: 異なるスレッド間でオブジェクトを操作する場合は注意が必要です。一般的なルールとして、関数は QThread オブジェクトを作成したスレッドからのみ呼び出すことができます(例:setPriority())。詳細はスレッドの同期を参照してください。

スレッドの管理

QThread はスレッドがstarted() やfinished() になるとシグナルで通知します。また、isFinished() やisRunning() を使ってスレッドの状態を問い合わせることもできます。

スレッドを停止するには、exit() またはquit() を呼び出す。極端な場合、実行中のスレッドを強制的にterminate() したくなることもある。しかし、これは危険であり、お勧めできません。詳細については、terminate() およびsetTerminationEnabled() のドキュメントをお読みください。

スレッドが終了したときに、そのスレッドに存在するオブジェクトの割り当てを解除したい場合がよくあります。これを行うには、finished() シグナルをQObject::deleteLater() に接続します。

他のスレッドの実行が終了するまで(または指定した時間が経過するまで)、wait ()を使用して呼び出し元のスレッドをブロックします。

QThreadは、静的でプラットフォームに依存しないスリープ関数も提供しています。sleep()、msleep()、usleep()では、それぞれフル秒、ミリ秒、マイクロ秒の分解能を実現しています。

注: wait ()とsleep ()関数は、Qtはイベントドリブン・フレームワークなので、一般的には不要です。wait() の代わりに、finished() シグナルをリッスンしてください。sleep() 関数の代わりに、QChronoTimer を使うことを検討してください。

静的関数currentThreadId() とcurrentThread() は、現在実行中のスレッドの識別子を返します。前者はスレッドのプラットフォーム固有の ID を返し、後者は QThread ポインタを返します。

スレッドに付けられる名前(たとえば Linux ではps -L というコマンドで識別される)を選択するには、スレッドを開始する前にsetObjectName() を呼び出します。setObjectName()を呼び出さない場合、スレッドに与えられる名前は、スレッド・オブジェクトのランタイム・タイプのクラス名になります(例えば、マンデルブロの例の場合、"RenderThread" 、これはQThreadのサブクラスの名前です)。これは現在Windowsのリリースビルドでは利用できないことに注意してください。

QtのスレッドサポートQThreadStorageスレッドの同期マンデルブロセマフォを使用したProducerとConsumer待機条件を使用したProducerとConsumerも参照してください

メンバ型ドキュメント

enum QThread::Priority

この列挙型は、オペレーティングシステムが新しく作成されたスレッドをどのようにスケジュールするかを示す。

定数説明
QThread::IdlePriority0他のスレッドが実行されていない時のみスケジューリングされる。
QThread::LowestPriority1LowPriority よりも少ない頻度でスケジューリングされる。
QThread::LowPriority2NormalPriority よりも低い頻度でスケジューリングされる。
QThread::NormalPriority3オペレーティング・システムのデフォルトの優先度。
QThread::HighPriority4NormalPriorityよりも頻繁にスケジュールされる。
QThread::HighestPriority5HighPriorityよりも頻繁にスケジュールされる。
QThread::TimeCriticalPriority6できるだけ頻繁にスケジュールされる。
QThread::InheritPriority7作成スレッドと同じ優先度を使用する。これがデフォルトである。

メンバ関数ドキュメント

[explicit] QThread::QThread(QObject *parent = nullptr)

新しいスレッドを管理するために新しい QThread を構築する。parent が QThread の所有権を持つ。スレッドはstart() が呼び出されるまで実行を開始しません。

start()も参照してください

[virtual noexcept] QThread::~QThread()

QThread を破棄します。

QThread オブジェクトを削除しても、それが管理するスレッドの実行は停止しないことに注意してください。実行中のQThread を削除する(つまり、isFinished() がfalse を返す)と、プログラムがクラッシュします。QThread を削除する前に、finished() シグナルを待ってください。

Qt 6.3 以降では、対応するスレッドがまだ実行中であっても、QThread::create() の呼び出しによって作成されたQThread インスタンスを削除することができます。このような場合、Qt はスレッドに割り込み要求を出し(requestInterruption() で)、スレッドのイベントループ(もしあれば)に終了を求め(quit() で)、スレッドが終了するまでブロックします。

create()、isInterruptionRequested()、exec()、quit()も参照

[static] template <typename Function, typename... Args> QThread *QThread::create(Function &&f, Args &&... args)

引数args で関数f を実行する新しいQThread オブジェクトを作成します。

新しいスレッドは開始されません。start() を明示的に呼び出して開始する必要があります。これにより、スレッドのシグナルに接続したり、QObject をスレッドに移動したり、新しいスレッドの優先順位を選択したりすることができます。関数f は新しいスレッドで呼び出されます。

新しく作成されたQThread インスタンスを返します。

注意: 呼び出し元は、返されたQThread インスタンスの所有権を取得します。

警告: 返されたQThread インスタンスに対して、start() を複数回呼び出さないでください。そうすると、未定義の動作になります。

start()も参照

[static] QThread *QThread::currentThread()

現在実行中のスレッドを管理するQThread へのポインタを返します。

[static noexcept] Qt::HANDLE QThread::currentThreadId()

現在実行中のスレッドのスレッド・ハンドルを返します。

警告: この関数が返すハンドルは内部目的で使用されるため、アプリケーション・コードで使用してはならない。

注意 : Windows では、この関数は Win32 関数 GetCurrentThread() によって返される擬似 HANDLE (Windows-Thread HANDLE) ではなく、Win32 関数 GetCurrentThreadId() によって返される DWORD (Windows-Thread ID) を返します。

[override virtual] bool QThread::event(QEvent *event)

再インプリメント:QObject::event(QEvent *e)。

QAbstractEventDispatcher *QThread::eventDispatcher() const

スレッドのイベントディスパッチャオブジェクトへのポインタを返します。スレッドにイベント・ディスパッチャが存在しない場合、この関数はnullptr を返します。

setEventDispatcher()も参照してください

[protected] int QThread::exec()

イベント・ループに入り、exit() が呼び出されるまで待機し、exit() に渡された値を返す。quit() 経由でexit() が呼び出された場合、返される値は 0 である。

この関数は、run ()内から呼び出すことを想定している。イベント処理を開始するには、この関数を呼び出す必要があります。

注: これはスレッド自身の中、つまりカレント・スレッドであるときにのみ呼び出すことができる。

quit() およびexit()も参照のこと

[slot] void QThread::exit(int returnCode = 0)

スレッドのイベント・ループに、リターン・コードで終了するように指示する。

この関数を呼び出すと、スレッドはイベント・ループから離れ、QEventLoop::exec() の呼び出しから戻る。QEventLoop::exec() 関数はreturnCode を返す。

慣例により、returnCode の0は成功を意味し、0以外の値はエラーを示す。

同名の C ライブラリ関数とは異なり、この関数は呼び出し元に戻ることに注意してください。

このスレッドでは、QThread::exec ()が再度呼び出されるまで、QEventLoopはもう開始されない。QThread::exec() のイベントループが実行されていない場合、QThread::exec() の次の呼び出しも即座に戻ります。

注意:この関数はスレッドセーフである。

quit() およびQEventLoopも参照のこと

[private signal] void QThread::finished()

このシグナルは、関連スレッドが実行を終了する直前に発せられる。

このシグナルが発せられたとき、イベント・ループの実行はすでに停止している。遅延された削除イベントを除き、スレッド内でこれ以上イベントが処理されることはありません。このシグナルをQObject::deleteLater() に接続することで、そのスレッド内のオブジェクトを解放することができます。

注意: 関連するスレッドがterminate() を使用して終了された場合、このシグナルがどのスレッドから発せられるかは未定義である。

注意: これはプライベート・シグナルである。シグナル接続で使用することはできますが、ユーザーが発することはできません。

started()も参照

[static noexcept] int QThread::idealThreadCount()

このプロセスが並行して実行できる理想的なスレッド数を返します。これは、このプロセスで使用可能な論理プロセッサ数(このOSでサポートされている場合)またはシステム内の論理プロセッサの総数を問い合わせることで行われる。どちらの値も決定できなかった場合、この関数は 1 を返す。

注意 : 全ての論理プロセッサのサブセットへのスレッドのアフィニティ設定をサポートするオペレーティングシステムでは、この関数が返す値はスレッド間や時間の経過とともに変化する可能性があります。

注意 :CPUのホットプラグとホットアンプラグをサポートするオペレーティングシステムでは、この関数が返す値も時間の経過とともに変化する可能性があります(また、CPUは物理的なハードウェアの変更なしに、ソフトウェアによってオン/オフできることに注意してください)。

[noexcept, since 6.8] bool QThread::isCurrentThread() const

このスレッドがQThread::currentThread であれば true を返します。

この関数は Qt 6.8 で導入されました。

currentThreadId()も参照してください

bool QThread::isFinished() const

スレッドが終了した場合はtrue を返し、そうでない場合はfalse を返します。

注意:この関数はスレッドセーフです。

isRunning()も参照して ください。

bool QThread::isInterruptionRequested() const

このスレッドで実行中のタスクを停止する必要がある場合は真を返す。中断はrequestInterruption() で要求できる。

この関数は、長時間実行中のタスクをきれいに割り込み可能にするために使用できる。この関数が返す値をチェックしたり操作したりすることはありません。オーバーヘッドを低く保つために、あまり頻繁に呼び出さないように注意してください。

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

注意: この関数は、スレッド自身の中、つまりカレント・スレッドであるときにのみ呼び出すことができます。

currentThread() およびrequestInterruption()も参照

[static noexcept, since 6.8] bool QThread::isMainThread()

現在実行中のスレッドがメインスレッドであるかどうかを返します。

メイン・スレッドとは、QCoreApplication が作成されたスレッドのことである。これは通常、main() 関数を呼び出したスレッドですが、必ずしもそうではありません。GUIイベントを処理しているスレッドであり、グラフィカル・オブジェクト (QWindow,QWidget) を作成できるスレッドです。

この関数はQt 6.8で導入されました。

currentThread() およびQCoreApplication::instance()も参照してください

bool QThread::isRunning() const

スレッドが実行中であればtrue を返し、そうでなければfalse を返します。

注意:この関数はスレッドセーフです。

isFinished()も参照して ください。

int QThread::loopLevel() const

スレッドの現在のイベント・ループ・レベルを返します。

注: この関数は、スレッド自身、つまりスレッドが現在のスレッドであるときにのみ呼び出すことができます。

[static] void QThread::msleep(unsigned long msecs)

この関数はオーバーロードされた関数であり、call.Time()と等価である:

QThread::sleep(std::chrono::milliseconds{msecs});

注意: この関数は正確さを保証するものではありません。高負荷状態では、アプリケーションはmsecs よりも長くスリープする可能性があります。OSによっては、msecs を10msや15msに切り上げることがある。

sleep() およびusleep()も参照のこと

QThread::Priority QThread::priority() const

実行中のスレッドの優先度を返す。スレッドが実行中でない場合、この関数はInheritPriority を返す。

PrioritysetPriority()、start() も参照

[slot] void QThread::quit()

スレッドのイベント・ループに、リターン・コード 0(成功)で終了するように指示する。QThread::exit(0)を呼び出すのと同じ。

スレッドがイベント・ループを持っていない場合、この関数は何もしない。

注意:この関数はスレッドセーフです。

exit() およびQEventLoopも参照のこと

void QThread::requestInterruption()

スレッドの中断を要求する。この要求は勧告的なものであり、スレッド上で実行されているコード次第で、そのような要求に対してどのように対処すべきかを決めることができる。この関数は、スレッド上で実行されているイベントループを停止させることはなく、スレッドを終了させることもない。

注意:この関数はスレッドセーフです。

isInterruptionRequested()も参照のこと

[virtual protected] void QThread::run()

スレッドの開始点。start() を呼び出した後、新しく作成されたスレッドはこの関数を呼び出します。デフォルトの実装では、単にexec() を呼び出します。

高度なスレッド管理を容易にするために、この関数を再実装できます。このメソッドからリターンすると、スレッドの実行が終了します。

start() およびwait()も参照して ください。

void QThread::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)

スレッドのイベント・ディスパッチャをeventDispatcher に設定します。 これは、スレッドにまだイベント・ディスパッチャがインストールされていない場合にのみ可能です。

イベント・ディスパッチャは、メイン・スレッドではQCoreApplication がインスタンス化されたときに、補助スレッドではstart() のときに自動的に作成されます。

このメソッドはオブジェクトのオーナーシップを取ります。

eventDispatcher()も参照してください

void QThread::setPriority(QThread::Priority priority)

この関数は、実行中のスレッドに対してpriority を設定する。スレッドが実行中でない場合、この関数は何もせず、すぐに戻ります。特定の優先度を持つスレッドを起動するには、start() を使用する。

引数priority には、InheritPriority を除くQThread::Priority 列挙型の任意の値を指定できる。

priority パラメータの効果は、オペレーティング・システムのスケジューリング・ポリシーに依存する。特に、スレッド優先度をサポートしていないシステム(Linuxなど、詳しくは http://linux.die.net/man/2/sched_setscheduler を参照)では、priority は無視される。

Prioritypriority()、start()も参照の こと。

void QThread::setStackSize(uint stackSize)

スレッドのスタック・サイズをstackSize に設定する。stackSize がゼロの場合、オペレーティング・システムまたはランタイムはデフォルト値を選択する。そうでない場合、スレッドのスタック・サイズは指定された値(切り上げまたは切り下げが可能)になる。

ほとんどのオペレーティングシステムでは、スタックに割り当てられるメモリの量は、最初はstackSize より小さく、スレッドがスタックを使用するにつれて大きくなる。このパラメータは、スタックの最大サイズを設定する(つまり、スタックが占有することを許される仮想メモリ空間のサイズを設定する)。

この関数は、スレッドが開始される前にのみ呼び出すことができる。

警告 ほとんどのオペレーティング・システムでは、スレッドのスタック・サイズに最小と最大の制限を設けています。スタック・サイズがこれらの制限を外れると、スレッドは起動に失敗する。

stackSize()も参照

[static protected] void QThread::setTerminationEnabled(bool enabled = true)

enabled パラメータに基づいて、現在のスレッドの終了を有効または無効にする。スレッドはQThread によって開始されていなければならない。

enabled が false の場合、終了は無効となる。今後QThread::terminate() を呼び出すと、何も行われずに即座に返される。代わりに、終了が有効になるまで、終了は延期される。

enabled がtrueの場合、終了が有効になる。今後QThread::terminate() を呼び出すと、スレッドは正常に終了する。終了が延期された場合(つまり、終了が無効な状態でQThread::terminate() が呼び出された場合)、 この関数は呼び出し元のスレッドを直ちに終了する。この場合、この関数は戻らないことに注意。

terminate()も参照のこと

[static, since 6.6] void QThread::sleep(std::chrono::nanoseconds nsecs)

nsecs の間、現在のスレッドを強制的にスリープさせる。

与えられた条件が変化するのを待つ必要がある場合は、この関数の使用は避けてください。代わりに、変化を示すシグナルにスロットを接続するか、イベント・ハンドラ(QObject::event() を参照)を使用します。

注意: この関数は正確さを保証するものではありません。負荷が高い状況では、アプリケーションはnsecs よりも長くスリープする可能性があります。

この関数は Qt 6.6 で導入されました。

[static] void QThread::sleep(unsigned long secs)

現在のスレッドを強制的にsecs 秒間スリープさせます。

これはオーバーロードされた関数で、呼び出しと同等です:

QThread::sleep(std::chrono::seconds{secs});

msleep() およびusleep()も参照してください

uint QThread::stackSize() const

スレッドの最大スタックサイズを返します(setStackSize() で設定されている場合)。

setStackSize() も参照

[slot] void QThread::start(QThread::Priority priority = InheritPriority)

run() を呼び出してスレッドの実行を開始する。オペレーティング・システムは、priority パラメータに従ってスレッドをスケジューリングする。スレッドがすでに実行されている場合、この関数は何もしない。

priority パラメータの効果は、オペレーティング・システムのスケジューリング・ポリシーに依存する。特に、スレッド優先度をサポートしていないシステム(Linuxなど)では、priority は無視される(詳細はsched_setschedulerのドキュメントを参照)。

run() およびterminate()も参照の こと。

[private signal] void QThread::started()

このシグナルは、run ()関数が呼ばれる前に、関連スレッドが実行を開始したときに発せられる。

注意: これはプライベート・シグナルです。シグナル接続で使用することはできますが、ユーザーが発することはできません。

finished()も参照のこと

[slot] void QThread::terminate()

スレッドの実行を終了する。スレッドは、オペレーティング・システムのスケジューリング・ポリシーによって、即座に終了する場合としない場合があります。念のため、terminate() の後にQThread::wait() を使用してください。

スレッドが終了すると、そのスレッドの終了を待っていたすべてのスレッドが起動します。

警告: この関数は危険であるため、使用は推奨されない。スレッドはコード・パスのどの時点でも終了させることができる。スレッドは、データの変更中に終了させることができる。スレッドが自分自身の後始末をしたり、保持されているミューテックスのロックを解除したりする機会はない。要するに、この関数は絶対に必要な場合にのみ使用すること。

終了は、QThread::setTerminationEnabled ()を呼び出すことで、明示的に有効にも無効にもできる。終了が無効になっているときにこの関数を呼び出すと、終了は延期され、終了が再度有効になるまで延期される。詳細については、QThread::setTerminationEnabled() のドキュメントを参照のこと。

注意:この関数はスレッドセーフである。

setTerminationEnabled()も参照のこと

[static] void QThread::usleep(unsigned long usecs)

この関数はオーバーロードされた関数であり、call.Time()と同等である:

QThread::sleep(std::chrono::microseconds{secs});

注意: この関数は正確さを保証するものではない。高負荷状態では、アプリケーションはusecs よりも長くスリープする可能性がある。OSによっては、usecs を10msまたは15msに切り上げる場合がある。Windowsでは、1msの倍数に切り上げられる。

sleep() およびmsleep()も参照のこと

bool QThread::wait(QDeadlineTimer deadline = QDeadlineTimer(QDeadlineTimer::Forever))

これらの条件のいずれかが満たされるまで、スレッドをブロックする:

  • このQThread オブジェクトに関連付けられたスレッドが実行を終了したとき(つまり、run() から戻ったとき)。スレッドが終了した場合、この関数は真を返します。スレッドがまだ開始されていない場合も真を返す。
  • deadline に達した。この関数は、期限に達した場合に false を返します。

QDeadlineTimer::Forever (デフォルト)に設定されたデッドライン・タイマーがタイムアウトすることはありません。この場合、この関数は、スレッドがrun ()から戻るか、スレッドがまだ開始されていない場合にのみ戻ります。

これはPOSIXのpthread_join() 関数と同様の機能を提供する。

sleep() およびterminate()も参照のこと

bool QThread::wait(unsigned long time)

これはオーバーロードされた関数である。

time はミリ秒単位の待ち時間である。 が ULONG_MAX の場合、待ち時間がタイムアウトすることはない。time

[static] void QThread::yieldCurrentThread()

実行可能なスレッドがあれば、現在のスレッドの実行を他の実行可能なスレッドに譲る。どのスレッドに切り替えるかはオペレーティングシステムが決定することに注意してください。

©2024 The Qt Company Ltd. 本文書に含まれる文書の著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。