在多线程应用程序中使用随机的正确方法

本文关键字:方法 随机 多线程 应用程序 | 更新日期: 2023-09-27 18:34:38

Ok.以下是我知道的行不通的:

int Rand()
{
    //will return the same number over and over again
    return new Random().Next();
}
static Random rnd=new Random();
int Rand()
{
    //if used like this from multiple threads, rnd will dissintegrate 
    //over time and always return 0
    return rnd.Next();
}

这将正常工作,但如果被多个线程使用,CPU 使用率会上升,这是我不想要的,我认为这是不必要的:

int Rand()
{
    lock(rnd)
    {
        return rnd.Next();
    }
}

那么,是否有适用于 c# 的线程安全随机类,或者更好的使用它的方法?

在多线程应用程序中使用随机的正确方法

我使用这样的东西:

public static class StaticRandom
{
    static int seed = Environment.TickCount;
    static readonly ThreadLocal<Random> random =
        new ThreadLocal<Random>(() => new Random(Interlocked.Increment(ref seed)));
    public static int Rand()
    {
        return random.Value.Next();
    }
}
readonly ThreadLocal<Random> random = 
    new ThreadLocal<Random>(() => new Random(GetSeed()));
int Rand()
{
    return random.Value.Next();
}
static int GetSeed()
{
    return Environment.TickCount * Thread.CurrentThread.ManagedThreadId;
}

(无耻地从杰罗恩·范内维尔的评论中窃取(

我认为你想要的是线程静态

[ThreadStatic]
static Random rnd=new Random();
int Rand()
{
    if ( rnd == null ) 
    {
       rnd = new Random()
    }
    //Now each thread gets it's own version
    return rnd.Next();
}

这样,每个线程都会获得自己的 rnd 属性版本

锁定会增加 CPU 使用率的原因是,所有线程都将等待该单点(只有在您经常使用它时才应该是一个问题(

[更新] 我修复了初始化。正如有人指出的那样,它确实留下了一个事实,即如果您在同一毫秒内启动多个线程,那么它们将产生相同的结果。

我的小组最近对此进行了调查。我们得出的结论是,我们应该使用专门为支持并行计算而设计的随机数生成器。Tina的随机数生成器库(http://numbercrunch.de/trng/(有一个稳定的实现,以及一本带有理论介绍和相关文献参考的手册。到目前为止,我们对此非常满意。