「Qtの基礎 - マルチスレッド」の版間の差分

ナビゲーションに移動 検索に移動
295行目: 295行目:
<br>
<br>
優先順位の逆転の問題がある場合、 [http://www.bogotobogo.com/cplusplus/multithreaded.php#priority_inversion 優先順位の逆転]を参照すること。<br>
優先順位の逆転の問題がある場合、 [http://www.bogotobogo.com/cplusplus/multithreaded.php#priority_inversion 優先順位の逆転]を参照すること。<br>
<br><br>
== QMutexクラス ==
QMutexクラスは、スレッド間のアクセスシリアル化を提供する。
QMutexの目的は、オブジェクト、データ構造、ソースコードのセクションを保護して、1度に1つのスレッドのみがアクセスできるようにする。(同期)
一般的に、QMutexLockerでミューテックスを使用することが最適である。
これにより、ロックとロック解除が一貫して実行されるようになる。
<syntaxhighlight lang="c++">
QMutex::QMutex(RecursionMode mode = NonRecursive)
</syntaxhighlight>
<br>
# QMutexクラスのインスタンスを生成して、新しいミューテックスを構築する。<br>ミューテックスは、ロック解除された状態で生成される。
# ミューテックスのモードがQMutex::Recursiveの場合、スレッドは同じミューテックスを複数回ロックでき、<br>対応する数のunlockメソッドの呼び出しが行われるまで、ミューテックスのロックは解除されない。
# それ以外の場合、スレッドはミューテックスを1回だけロックできる。<br>モードを指定しない場合は、QMutex::NonRecursiveが指定される。
<br>
<center>
表. enum QMutex::RecursionMode<br>
{| class="wikitable" style="background-color:#fefefe;"
|-
! style="background-color:#00ffff;" | 定数
! style="background-color:#00ffff;" | 値
! style="background-color:#00ffff;" | 説明
|-
| QMutex::Recursive || 1 || スレッドは、同じミューテックスを複数回ロックでき、<br>対応する数のunlockメソッドの呼び出しが行われるまで、ミューテックスはロック解除されない。
|-
| QMutex::NonRecursive || 0 || スレッドは、ミューテックスを1回だけロックできる。
|}
</center>
<br>
以下の例では、スレッドの動作を制御するためのメンバ変数bStopを定義している。
変数bStopがtrueの場合、スレッドはループから抜ける。
したがって、1つのスレッドからのみアクセスする必要があり、ミューテックスのロックを使用している。
<syntaxhighlight lang="c++">
// main.cppファイル
#include <QCoreApplication>
#include <QDebug>
#include "mythread.h"
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    // creating three thread instances
    MyThread thread1("A"), thread2("B"), thread3("C");
    qDebug() << "hello from GUI thread " << a.thread()->currentThreadId();
    // thread start -> call run()
    thread1.start();
    thread2.start();
    thread3.start();
    return a.exec();
}
</syntaxhighlight>
<br>
<syntaxhighlight lang="c++">
// mythread.hファイル
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include <QString>
class MyThread : public QThread
{
public:
    // constructor
    // set name and Stop is set as false by default
    MyThread(QString s, bool b = false);
    // overriding the QThread's run() method
    void run();
    // variable that mutex protects
    bool bStop;
private:
    QString name;
};
#endif // MYTHREAD_H
</syntaxhighlight>
<br>
<syntaxhighlight lang="c++">
// mythread.cppファイル
#include "mythread.h"
#include <QDebug>
#include <QMutex>
MyThread::MyThread(QString s, bool b) : name(s), bStop(b)
{
}
// run() will be called when a thread starts
void MyThread::run()
{
    qDebug() << this->name << " " << this->Stop;
    for(int i = 0; i <= 5; i++)
    {
        QMutex mutex;
        // prevent other threads from changing the "Stop" value
        mutex.lock();
        if(this->bStop) break;
        mutex.unlock();
        qDebug() << this->name << " " << i;
    }
}
</syntaxhighlight>
<br>
# 出力
hello from GUI thread  0x1364
"A"  false
"C"  false
"C"  0
"A"  0
"A"  1
"A"  2
"A"  3
"B"  false
"C"  2
"C"  3
"C"  4
...略
<br><br>
<br><br>


__FORCETOC__
__FORCETOC__
[[カテゴリ:Qt]]
[[カテゴリ:Qt]]

案内メニュー