如何实现线程安全的随机数
试图找到并理解在 .NET Core 2.x 或更高版本中实现线程安全数字生成器的最佳方法
首先我发现了这一点 - https://web.archive.org/web/20160326010328/http://blogs.msdn.com/b/pfxteam/archive/2009/02/19/9434171.aspx
阅读完后在我看来,有几种“好”方法 -
- ThreadStatic Random 实例,带有全局随机实例来生成种子
- 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();
}
}
Trying to find and understand the best approach to implement a thread-safe number generator in .NET Core 2.x or higher
First Iv'e found this -
https://web.archive.org/web/20160326010328/http://blogs.msdn.com/b/pfxteam/archive/2009/02/19/9434171.aspx
After reading through it seems to me like there are couple of "good" ways -
- ThreadStatic Random instance, with a global random instance to generate seeds
- ThreadStatic Random instance, with a global RNGCryptoServiceProvider to generate seeds
Where basically you choose the latter if a strong cryptographically random is a requirement.
After some additional research I found out that since .NET Core 2.x System.Random class was revised, therefore the default seed generation which is no longer primary dependent on the system timer.
(https://blogs.siliconorchid.com/post/coding-inspiration/randomness-in-dotnet)
Question -
How does this affect the implementation of a thread-safe random class?
Refrencing the first link Iv'e shared code solution -
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();
}
}
Since dotnet core 2.x adjustments is a global locked seed generator even required? or a basic ThreadStatic random instance is all thats needed? such as -
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();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
从 .NET 6 开始,您可以使用
Random.Shared
获取Random
的线程安全实例。文件是这样说的:
https://learn.microsoft.com /en-us/dotnet/api/system.random.shared?view=net-6.0
无需再花哨了。
要获得随机整数,您只需执行以下操作:
如果您想要密码学上的强随机性,那么 Eric Lippert 的
BetterRandom
是正确的选择:从这里开始阅读更多内容:https://ericlippert.com/2019/01/31/fixing-random-part-1/
From .NET 6 you can use
Random.Shared
to get a thread-safe instance ofRandom
.The documents say this:
https://learn.microsoft.com/en-us/dotnet/api/system.random.shared?view=net-6.0
There's no need to get fancy anymore.
To get a random integer you just need to do:
If you want cryptographically strong randomness, then Eric Lippert's
BetterRandom
is the way to go:Start here to read more: https://ericlippert.com/2019/01/31/fixing-random-part-1/
System.Random
类在使用默认构造函数实例化时使用的算法已更改为新算法,但该类仍然不是线程安全的,因此旧技术如使用[ThreadStatic] 仍然需要。
System.Random
,但如果您想生成随机秘密字符串,请使用RandomNumberGenerator
。System.Random
class use when instantiated with default constructor has changed to the new one, but the class is still not thread-safe, so old technique like using[ThreadStatic]
is still needed.RandomNumberGenerator
when you really want to make sure your random number is secure. For example, if you just want to display random daily messages, useSystem.Random
, but if you want to generate a random secret string, useRandomNumberGenerator
.