2016-10-19 3 views
1

私はpre C++ 11を使っています。そうでなければ、スレッドと原子変数をインクルードして私のニーズを満たすことができます。インスタンス化するといくつかのスレッドを開始するクラスを取得しました。1つのスレッドが変数に書き込みます。もう1つのスレッドは変数を読み込みます。どのようにしてその変数を保護しますか?

void ThisClass::ThisThread() 
{ 
    while (runThisThread) 
    { 
     // doing stuff 
    } 
} 

となり、他の機能::私のようなものを持っているスレッド立ち上げた関数内

void ThisClass::StopThisThread() 
{ 
    runThisThread = false; // 'runThisThread' variable is 'volatile bool' 
} 

スレッドが別のスレッドから割り当てられたインデックスに基づいてバッファを介して咀嚼されます。したがって、あるスレッドは他のスレッドが決して何もしない値を割り当てますが、その値を読み取ることになります。私の計画は、より揮発性の高いメモリを使用してそれらのインデックス値を割り当てることでした。しかし、この質問は私が揮発性メモリを間違って使用していることを示唆していますWhen to use volatile with multi threading?。 pre-C++ 11がこのようなマルチスレッドクラスのメモリを扱う正しい方法は何ですか?各スレッドがその変数を読み取ることができる間に、複数のスレッドが1つの変数を割り当てることを許可していないことに注意してください。

編集:これはクロスプラットフォームの必要がないWindowsプログラムであることを忘れてしまった。私は私のスレッドのためにAfxwin.h AfxBeginThread()を使用しています。

+1

あなたはアトミック変数またはミューテックスのいずれかをしたいです。私はそれらを研究するためにOPに練習として残す。 – UKMonkey

+5

あなたが使用するスレッドAPIのミューテックスを使用してください。 –

+0

使用しているAPIはどこかのチュートリアルが必要です。ミューテックスまたは同期メカニズムはどこかで言及されるべきです – Hayt

答えて

3

このシナリオは手動リセットevent object(または対応するCEvent MFCラッパー)を使用して解決するのが最も効果的です。スレッドを終了したいときは、イベントを通知するだけです。糸ループは、イベント状態を評価する必要があります。

while(!myEvent.Lock(0)) { 
    // doing stuff 
} 
+0

これは、スレッドの停止に機能します。しかし、それは質問の第二の部分に対処していません。 "スレッドは別のスレッドから割り当てられたインデックスに基づいてバッファを噛み砕くので、あるスレッドは他のスレッドが決して何もしない値を割り当てますが、その値を読み取ることになります。しかし、この質問は私が揮発性メモリを誤って使用していることを示唆していますマルチスレッドでvolatileを使用するのはいつですか?あるスレッドが割り当て、別のスレッドが読み込むint変数が必要です。 –

+0

@ブラッドB:質問を読んだとき、それは私には分かりませんでした。移植性のないソリューションでは、volatile intとコンパイラswitch/volatile:ms(非ARMアーキテクチャのデフォルト)を使用することができます。コンパイラ間で移植可能なものが必要な場合は、[同期](https://msdn.microsoft.com/en-us/library/windows/desktop/ms686353.aspx)機能(SRWLやInterlockedXyz APIなど)を選択できます)。 – IInspectable

+0

遅れて申し訳ありません。あなたの答えを正しいものとして選択しました。私はこの質問を見る将来の人物を追加したかったのです。 Windows 7以前のものは非ARMアーキテクチャです。マイクロソフトではWindows 7以前のバージョンをサポートしていないため、これらのマシンのいずれかを使用している場合は、volatileにするのが安全です。msは選択されたオプションです。 –

0

連動機能を使用するために書かれたように、コードをされたまま、これを処理する最も効率的な方法:

while(::WaitForSingleObject(hEvent, 0) == WAIT_TIMEOUT) { 
    // doing stuff 
} 

それともMFCのバージョンなど

volatile DWORD runThisThread; 

void ThisClass::ThisThread() 
{ 
    while (InterlockedCompareExchange(&runThisThread, 0, 0)) 
    { 
     // doing stuff 
    } 
} 

void ThisClass::StopThisThread() 
{ 
    InterlockedExchange(&runThisThread, false); 
} 

これは、クリティカルセクションを使用して変数を保護したり、変数をイベントオブジェクトで置き換えるよりもはるかに高速です。

(ただし、あなたがビジーウェイトを避けるために、イベントオブジェクトを使用する必要がありその後、より多くの仕事を待っている間に、あなたのループは、たとえば、アイドルする必要がある場合。)

関連する問題