C / C ++のほとんどすべての疑似乱数ジェネレーター(Mersenne、...)は、ある種の内部状態、通常はバイトの短いベクトルを使用します。私の質問は、そのようなランダムジェネレーターがマルチスレッド環境で使用および共有される場合、スレッドセーフにするか、「競合状態」を発生させることでランダム性を高めることしかできないのでしょうか。
この質問に厳密に答えるのは非常に難しいことを私は知っていますが、どんな意見でも歓迎します。
「競合状態」を発生させると、すべてが台無しになる可能性があります。技術的には、データ競合は未定義の動作であるため、ピザを注文する可能性があります。
しかし、それが起こらなくても、内部状態が壊れる可能性が高く、ランダム シーケンスのすべての重要なプロパティが失われるだけです。たとえば、均一性を保証できなくなります。乱数の生成を偶然に任せることはできません。
競合状態を発生させることは決して良いことではありません。コードがクラッシュする可能性があります。そうでない場合でも、生成される数値の品質が低下することはほぼ確実です。人々は乱数発生器の設計に多大な労力を費やしており、この種のノイズを挿入すると、その努力が台無しになる可能性が非常に高くなります。
内部状態の種類に大きく依存します。考えられるすべてのビットパターンが内部状態の有効な表現であり、したがって乱数シーケンスのある時点で発生する場合は、書き込みレースが発生しても問題はありません。しかし、引用したメルセンヌを含む多くの乱数ジェネレーターは、256の累乗ではない周期を持っているため、シングルスレッド操作では到達せず、マルチスレッド操作で問題を引き起こす可能性のあるいくつかの状態パターンがあります。
ただし、rngをスレッドセーフにするさらに良い理由があります。そうしないと、2つのプロセスが同じ状態を読み取ってから、どちらかが更新できるようになる可能性があります。これにより、2つのプロセスがまったく同じ乱数を共有する可能性があり、アプリケーションによっては、あらゆる種類の奇妙な問題が発生する可能性があります。ミューテックスまたはスレッドローカル状態のいずれかを使用して、スレッドsdafeにすることができます。