12,982
回編集
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]] |