2015-12-20 12 views
5

私は先週のOSクラスを受け取り、同時実行性/スレッド化プロジェクトを持っていました。それは飛行機に上陸した/彼らが風が吹いている方向に離陸させた空港シムだった。私たちはJavaでやる必要がありました。今度は決勝戦が終わって退屈だから、C++ 11でやろうとしています。 Javaでは、メインの風(0〜360)の同期変数を使用し、使用していた3つのスレッドに渡しました。私の質問です:あなたはC + + 11でそれを行うことはできますか?それは基本的なリーダー/ライターであり、1つのスレッドは風を書き/更新し、もう1つは離陸/離陸します。C++でのシェア変数11

「threads.cpp」実装ファイルにグローバルな風変わりの変数を設定することで、動作するようになりました。しかし、私が望むだけ多くのスレッドに変数を渡す方法はありますか?それらのすべてがそれに追いついていますか?それとも、グローバル変数を使用して何も渡さない方が良いのですか(なぜ/なぜですか?)私はstd::ref()を見ていましたが、うまくいきませんでした。

EDIT:私は既にmutexとlock_guardを使用しています。私はすべてのスレッドで変数を最新のものにして渡す方法を理解しようとしています。今は書き込みスレッドでのみ更新されます。

答えて

5

std::lock_guardstd::mutexを使用すると、共有データへのアクセスを同期できます。共有データが整数に収まる場合は、ロックなしでstd::atomic<int>を使用できます。

グローバル変数を避けたい場合は、共有状態のアドレスをスレッド関数に渡すだけです。たとえば、次のように

void thread_entry1(std::atomic<int>* val) {} 
void thread_entry2(std::atomic<int>* val) {} 

std::atomic<int> shared_value; 
std::thread t1(thread_entry1, &shared_value); 
std::thread t2(thread_entry2, &shared_value); 
+0

これはまさに私がやろうとしていたものです!しかし、それはグローバル変数を使用しているだけで痛みを感じるようです。このようにして+/-がありますか? – lciamp

+3

さて、ほとんどの人は、グローバル変数はほとんどの場合、貧弱な実践であると考えています。少なくともテストは難しくなります。 –

1

あなたはstd::shared_ptrを通じてnewとヒープ上に、たとえば風のオブジェクトを作成することもできます。このポインタを関心のあるすべてのスレッドに渡し、std::mutexstd::lock_guardを使用して変更します。

+0

ありがとうございます。私はshared_ptrをチェックアウトする必要があります。私はC++ 98から11への変更を行っています。楽しい冬休みになるはずです! – lciamp

+1

また、JavaからC++への変更も行っています。これは頭を悩ませる必要があるピボットポイントです。 Javaオブジェクトは自動的にヒープ上に作成され、メモリはあなたのために管理されます。 C++では、この責任を自分で負う必要があります。しかし、C++ 11(とC++ 14!)の標準ライブラリヘルパーは、できるだけ甘い旅をするために必要なものです.C++の土地にようこそ! :)) –

2

std::mutexstd::lock_guardを使用すると、Javaの同期化された変数と同じことが起こります(Javaでは、これはあなたが知らないうちに秘密裏に行われます)。

しかし、の1つのプロデューサー(風の方向は1つだけです)、それ以外の場合はコンシューマのみです。 std::atomic<int>を緩やかに並べ替え、それぞれの消費者からその変数を読み直してください。すべての航空機の世界的な見方が一貫しているという要件がない限り(ただし、ロックステップ・シミュレーションを実行する必要はありません)、同期の必要はありません。最終的にはいつでも飛行機の読み込みが正しく行われ、中間結果が乱れることはありません。つまり、アトミックな更新が必要です。
あなたが読んだものがすべて1つの値なので、万一起こったことを保証する必要がないので、緩やかなメモリの順序でも十分です。

アトミック更新(またはアトミック書き込み)は、それ以上ではない場合は少なくとも1桁以上の大きさです。緩やかな順序での原子の読み書きは、多くの(ほとんどの)主流のアーキテクチャでは普通の普通の読み書きです。

変数はグローバルである必要はなく、メインスレッドのsimultionループのスコープに保持してスレッドに参照(またはポインタ)を渡すこともできます。

+0

ハァッ。 mutex/lock_guardよりも原子のような音が私の問題に適しています。すでに書いたJavaコードを見ていたので、私がやっていたことは、参照ではなく値渡しでした。私はprobする必要があります。滑走路には風の原子を、滑走路にはmutex/lock_guardを使用します。助けてくれてありがとう! – lciamp

+0

滑走路用のミューテックスは、一度に滑走路上に1台の飛行機しか置くことができないため、意味をなさえます。現在の風向をサンプリングするためだけには本当にミューテックスは必要ありません。 – Damon

+0

std :: atomic を使うのは間違いなく機能しますが、これは時期尚早の最適化です。複数の変数(滑走路、風、...)があるので、状態全体を守るためのミューテックスが最初に留意すべきことです。 – galinette

関連する問題