试图找到并理解在 .NET Core 2.x 或更高版本中实现线程安全数字生成器的最佳方法
通读之后,我觉得有几个“好”的方法——
- ThreadStatic 随机实例,用全局随机实例生成种子
- ThreadStatic Random 实例,使用全局 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();
}
}
最佳答案
从 .NET 6 开始,您可以使用 Random.Shared
获取 Random
的线程安全实例。
文件是这样说的:
Provides a thread-safe Random instance that may be used concurrently from any thread.
https://learn.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/
关于c# - 如何实现线程安全的随机数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71238440/