試圖找到并理解在 .NET Core 2.x 或更高版本中實作執行緒安全數字生成器的最佳方法
首先我發現了這個 - https://web.archive.org/web/20160326010328/http://blogs.msdn.com/b/pfxteam/archive/2009/02/19/9434171.aspx
通讀后,在我看來,有幾種“好”的方法-
- ThreadStatic 隨機實體,用全域隨機實體生成種子
- ThreadStatic 隨機實體,帶有全域 RNGCryptoServiceProvider 來生成種子
如果需要強大的加密隨機性,基本上你會選擇后者。
經過一些額外的研究,我發現由于 .NET Core 2.x System.Random 類進行了修改,因此不再主要依賴于系統計時器的默認種子生成。(https://blogs.siliconorchid.com/post/coding-inspiration/randomness-in-dotnet)
問題 - 這如何影響執行緒安全隨機類的實作?
參考第一個鏈接 Iv'e 共享代碼解決方案 -
public static class RandomGen2
{
private static Random _global = new Random();
[ThreadStatic]
private static Random _local;
public static int Next()
{
Random inst = _local;
if (inst == null)
{
int seed;
lock (_global) seed = _global.Next();
_local = inst = new Random(seed);
}
return inst.Next();
}
}
由于 dotnet core 2.x 調整是否需要全域鎖定種子生成器?還是只需要一個基本的 ThreadStatic 隨機實體?如 -
public static class ThreadSafeRandom
{
[ThreadStatic]
private static Random _local;
public static int Next()
{
Random inst = _local;
if (inst == null)
{
_local = inst = new Random();
}
return inst.Next();
}
}
uj5u.com熱心網友回復:
從 .NET 6 開始,您可以使用它Random.Shared來獲取Random.
檔案是這樣說的:
提供一個執行緒安全的 Random 實體,可以從任何執行緒同時使用。
https://docs.microsoft.com/en-us/dotnet/api/system.random.shared?view=net-6.0
沒有必要再花哨了。
要獲得隨機整數,您只需執行以下操作:
int number = Random.Shared.Next();
如果您想要密碼學上的強隨機性,那么 Eric Lippert 的BetterRandom方法就是:
public static class BetterRandom
{
private static readonly ThreadLocal<System.Security.Cryptography.RandomNumberGenerator> crng = new ThreadLocal<System.Security.Cryptography.RandomNumberGenerator>(System.Security.Cryptography.RandomNumberGenerator.Create);
private static readonly ThreadLocal<byte[]> bytes = new ThreadLocal<byte[]>(() => new byte[sizeof(int)]);
public static int NextInt()
{
crng.Value.GetBytes(bytes.Value);
return BitConverter.ToInt32(bytes.Value, 0) & int.MaxValue;
}
public static double NextDouble()
{
while (true)
{
long x = NextInt() & 0x001FFFFF;
x <<= 31;
x |= (long)NextInt();
double n = x;
const double d = 1L << 52;
double q = n / d;
if (q != 1.0)
return q;
}
}
}
從這里開始閱讀更多內容:https ://ericlippert.com/2019/01/31/fixing-random-part-1/
uj5u.com熱心網友回復:
- 使用默認建構式實體化類時使用的演算法
System.Random已更改為新演算法,但該類仍然不是執行緒安全的,因此[ThreadStatic]仍然需要使用類似 using 的舊技術。 - 在 .NET Core 中,默認種子值由執行緒靜態偽亂數生成器生成。這意味著您不再需要實作全域種子生成器。
RandomNumberGenerator當你真的想確保你的亂數是安全的時使用。例如,如果您只想顯示隨機的每日訊息,請使用System.Random,但如果您想生成隨機秘密字串,請使用RandomNumberGenerator。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/432679.html
上一篇:為什么在使用多個等待時SynchronizationContext.Post()只被呼叫一次?
下一篇:解釋協程的有趣行為
