いいえC++ std
タイプはスレッドセーフではない方法でグローバルデータを使用します。このようなタイプの無関係な2つのインスタンスは、異なるスレッドでアクセスできます。
デフォルトでは、1つのタイプのインスタンスに、同期なしで2つのスレッドからアクセスすることはできません。
作成されたローカル変数。これらのローカル変数は、そのタイプの他のインスタンスとは無関係です。ここにはスレッドセーフの問題はありません。
疑似ランダム値は、状態を持ち再利用することで最も効率的に生成されます。あなたはこれをやっていないので、1から6までのあなたの乱数は、比較的高価なものになります。
std::random_device seeder;
std::mt19937 engine(seeder());
std::uniform_int_distribution<int> dist(1, 6);
return dist(engine);
std::mt19937
の使用は冗長です。 random_device
を既に作成しています。dist
に直接送信してからengine
を作成し、次にengine
を使用して作成しました。ここでengine
の使用は役に立たない。あなたは(mt19937
のように、いくつかのタイプの)engine
を作成
Traditionaly seeder
から一回。その後、engine
を保管し、それを配布に繰り返し渡します。
これは、エンジンスルーディストリビューションによって長い一連の擬似乱数を生成するために、比較的高価な「実数乱数」生成を一度行います。
ただし、このような使用にはコストがかかります。 engine
を格納する必要があります。また、複数スレッドへのアクセスを防止する必要があります。
これを行う「正しい」方法は、ランダムな値を生成するオブジェクトを用意し、必要な場所に渡すことです。使用された最初のシードを格納すると、関連する乱数のセットの実行を繰り返すこともできます。
あなたが明示的にランダムな状態の周りに渡すのアイデアを気に入らない場合は、(mutex
ガード付きまたはstatic
)thread_local
を使用することができます。
thread_local std::mt19937 engine(std::random_device{}());
std::uniform_int_distribution<int> dist(1, 6);
return dist(engine);
これは、スレッドごとに1 engine
を作成し、engine
はあなたのrandom_device
からの値で初期化されます。
なぜ「C」タグですか?これはCとは関係ありません。 – UnholySheep
なぜ私はdownvotesを受信しているのか分かりません。私はこれがスレッドセーフであるかどうか、また種を更新するために再実行するかどうかを尋ねています。 – cateof
おそらく、長くて詳細な回答がある同様の質問のためでしょうか? –