[解決済み] QMutexの使用方法について教えてください。
質問事項
私はQtの初心者で、Qtのマルチスレッドについて調べています。
で学んだように
Qt ドキュメント
2つのスレッドに対して2つのクラスを定義しました。
#include <QThread>
#include <QMutex>
class thread_a : public QThread
{
Q_OBJECT
public:
explicit thread_a(QObject *parent = 0);
int counter;
protected:
void run();
};
そしてCPPファイルでは
#include "thread_a.h"
thread_a::thread_a(QObject *parent) :
QThread(parent)
{
counter=0;
}
void thread_a::run()
{
counter++;
}
2つ目のスレッドクラスも同じですが
counter--
で
run()
メソッドを使用します。
そして、この2つのスレッドを
main.ccp
.
さて、私の質問です。
を共有するにはどうすればよいですか?
counter
で
thread_a
と
thread_b
を使って
QMutex
?
解決方法は?
データをスレッド内に持つのではなく、データをスレッド外に移動して保護し、両方のスレッドからアクセスできるようにします。
以下は、あなたができることのスケッチです。
class Counter
{
public:
Counter():mMutex(),mCounter(0){}
int inc()
{
QMutexLocker ml(&mMutex);
return mCounter++;
}
int dec()
QMutexLocker ml(&mMutex);
return mCounter--;
}
private:
QMutex mMutex;
int mCounter;
Q_DISABLE_COPY(Counter)
};
class ThreadA : public QThread
{
public:
ThreadA(Counter* ctr);
/* ... */
};
class ThreadB : public QThread
{
public:
ThreadB(Counter* ctr);
/* ... */
};
の構成は
Counter
がよく言われるのは
モニター
Wikipediaより引用(強調)。
並行プログラミングにおいて、モニターとは、複数のスレッドで安全に使用されることを目的としたオブジェクトまたはモジュールのことです。モニタの特徴は、そのメソッドが相互排除で実行されることです。つまり、各時点で、最大でも1つのスレッドがそのメソッドを実行することができます。これは 相互排除は、データ構造を更新する並列コードに関する推論と比較して、モニターの実装に関する推論を大幅に簡素化します。 .
この具体的なケースでは、より効率的な構成は次のようになります。
QAtomicInt
.
これは、特殊なCPU命令を使用することでアトミック性を獲得しています。
これは低レベルのクラスであり、他のスレッド構造を実装するために使用することができます。
Edit - 完全な例
スレッドと共有状態を正しく使用することは些細なことではありません。Qtのシグナルやスロットをキュー接続や他のメッセージベースのシステムで使用することを検討するとよいでしょう。
また、Adaのような他のプログラミング言語では、スレッドとモニター(保護されたオブジェクト)をネイティブな構造体としてサポートしています。
以下は完全な動作例です。
これは単なるサンプルコードです。
QTest::qSleep
を実際のコードで使用します。
objs.h
#ifndef OBJS_H
#define OBJS_H
#include <QtCore>
class Counter
{
public:
Counter(int init);
int add(int v);
private:
QMutex mMutex;
int mCounter;
Q_DISABLE_COPY(Counter)
};
class CtrThread : public QThread
{
Q_OBJECT
public:
CtrThread(Counter& c, int v);
void stop();
protected:
virtual void run();
private:
bool keeprunning();
Counter& mCtr;
int mValue;
bool mStop;
QMutex mMutex;
};
#endif
objs.cpp
#include "objs.h"
Counter::Counter(int i):
mMutex(),
mCounter(i)
{}
int Counter::add(int v)
{
QMutexLocker ml(&mMutex);
return mCounter += v;
}
///////////////////////////////////////
CtrThread::CtrThread(Counter& c, int v):
mCtr(c),
mValue(v),
mStop(false),
mMutex()
{}
void CtrThread::stop()
{
QMutexLocker ml(&mMutex);
mStop = true;
}
void CtrThread::run()
{
while(keeprunning())
{
mCtr.add(mValue);
}
}
bool CtrThread::keeprunning()
{
QMutexLocker ml(&mMutex);
return ! mStop;
}
test.cpp
#include <QtCore>
#include <QTest>
#include "objs.h"
int main(int argc, char** argv)
{
QCoreApplication app(argc, argv);
qDebug() << "Initalising";
Counter ctr(0);
CtrThread thread_a(ctr, +1);
CtrThread thread_b(ctr, -1);
qDebug() << "Starting Threads";
thread_a.start();
thread_b.start();
for (int i = 0; i != 15; ++i)
{
qDebug() << "Counter value" << ctr.add(0);
QTest::qSleep(1000);
}
qDebug() << "Stopping Threads";
thread_a.stop();
thread_b.stop();
thread_a.wait();
thread_b.wait();
qDebug() << "Finished";
return 0;
}
test.pro
QT=core testlib
HEADERS=objs.h
SOURCES=test.cpp objs.cpp
コンパイルして実行すると、値が出力されるのがわかります、サンプル出力です。
Initalising
Starting Threads
Counter value 0
Counter value 11057
Counter value 28697
Counter value 50170
Counter value 60678
Counter value 73773
Counter value 84898
Counter value 96441
Counter value 118795
Counter value 135293
Counter value 146107
Counter value 158688
Counter value 169886
Counter value 201203
Counter value 212983
Stopping Threads
Finished
関連
-
[解決済み] テスト
-
[解決済み】getline()が何らかの入力の後に使用されると動作しない 【重複あり
-
[解決済み】クラスのコンストラクタへの未定義参照、.cppファイルの修正も含む
-
[解決済み] 数値定数の前にunqualified-idを付けて、数値を定義することを期待する。
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)
-
[解決済み] 文字列の単語を反復処理するにはどうすればよいですか?
-
[解決済み] 1ビットのセット、クリア、トグルはどのように行うのですか?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み] スマートポインターとは何ですか?
-
[解決済み] 仮想デストラクタはいつ使うのか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++ 非推奨の文字列定数から「char*」への変換について
-
[解決済み】Visual Studio 2015で「非標準の構文。'&'を使用してメンバーへのポインターを作成します」エラー
-
[解決済み】クラステンプレートの引数リストがない
-
[解決済み】C++ - 解放されるポインタが割り当てられていないエラー
-
[解決済み] error: 'if' の前に unqualified-id を期待した。
-
[解決済み】関数名の前に期待されるイニシャライザー
-
[解決済み] クラスにデフォルトコンストラクタが存在しない。
-
[解決済み】エラー:strcpyがこのスコープで宣言されていない
-
[解決済み】リンカーエラーです。"リンカ入力ファイルはリンクが行われていないため未使用"、そのファイル内の関数への未定義参照
-
[解決済み】変数やフィールドがvoid宣言されている