相关疑难解决方法(0)

为什么这种双重检查锁定正确?(.净)

我已经阅读了很多关于双重检查锁定的危险,我会努力远离它,但据说说我认为它们是一个非常有趣的阅读.

我正在阅读Joe Duffy关于使用双重检查锁定实现单例的这篇文章:http: //www.bluebytesoftware.com/blog/PermaLink,guid,543d89ad-8d57-4a51-b7c9-a821e3992bf6.aspx

而他似乎提出的(变体)解决方案是这样的:

class Singleton {
private static object slock = new object();
private static Singleton instance;
private static int initialized;
private Singleton() {}
public Instance {
    get {
        if (Thread.VolatileRead(ref initialized) == 0) {
            lock (slock) {
                if (initialized == 0) {
                    instance = new Singleton();
                    initialized = 1;
                }
            }
        }
        return instance;
    }
}
Run Code Online (Sandbox Code Playgroud)

}

我的问题是,是否仍然存在写入重新排序的危险?具体来说这两行:

instance = new Singleton();
initialized = 1;
Run Code Online (Sandbox Code Playgroud)

如果这些写入被反转,那么其他一些线程仍然可以读取null.

c# concurrency singleton locking thread-safety

7
推荐指数
1
解决办法
814
查看次数

Microsoft是否更改了随机默认种子?

今天,我在.NET Core中进行了一些测试,并且遇到了一些有趣的事情。

以前(〜.NET Framework 4)Random使用过Environment.TickCount,但现在我相信情况已经改变。

考虑以下代码:

while (true)
{
    Random random = new Random();
    Console.WriteLine(random.Next(0, 10000));
}
Run Code Online (Sandbox Code Playgroud)

在较早的.NET Framework版本中,new Random()空构造函数将使用Environment.TickCount,这将导致伪随机值的重复。

因此,您可以期待如下结果:

542
4211
5244
5244
5244
9501
9501
Run Code Online (Sandbox Code Playgroud)

以此类推。

在使用最新编译器的最新.NET Core版本上,我收到以下结果:

5332
220
3928
524
2973
2840
4965
5667
657
6434
3170
3046
7044
Run Code Online (Sandbox Code Playgroud)

绝对可以改善。

在旧版本中,其他表现出此问题的SO问题:

如何生成随机整数?

在C#中生成没有重复的随机数

非重复随机数

C#随机数生成器线程安全吗?


我的设置:.NET Core 2.2 /最新的C#编译器。


实际问题

所以我的问题是,PRNG是否真的得到了改善,或者他们只是将构造函数更改为使用其他默认种子,如果是,则它们用作种子是什么?密码术现在是否更安全(如果他们实际上改变了实现)?

c# random

6
推荐指数
1
解决办法
141
查看次数

如何制作 ac# 线程安全的随机数生成器

我的代码中有一个循环

Parallel.For(0, Cnts.MosqPopulation, i => { DoWork() });
Run Code Online (Sandbox Code Playgroud)

但是在DoWork()函数中,有多个对随机数生成器的调用,其定义如下:

public static class Utils
{
    public static readonly Random random = new Random();

}
Run Code Online (Sandbox Code Playgroud)

它是静态实例,因此只播种一次。我可以在整个代码中使用它。

根据 MSDN 和其他 stackoverflow 线程,这不是线程安全的。事实上,我注意到有时我的代码会中断并且随机数生成器开始生成全零(根据 MSDN 文档)。

还有其他的 stackoverflow 线程,但是比较老,而且实现速度很慢。我不能在生成数字上浪费时间,因为该程序是一项科学计算,并且正在运行数百次模拟。

我从 2.0 天开始就没有使用过 .net,我不确定该语言是如何演变成能够制作快速、高效、线程安全的 RNG。

以下是之前的主题:

C# 随机数生成器线程安全吗?

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

用于 C# 的快速线程安全随机数生成器

注意:因为我需要一个快速的实现,所以我不能使用RNGCryptoServiceProvider相当慢的。

注2:我没有最少的工作代码。我什至不知道从哪里开始,因为我不知道线程安全是如何工作的,也不知道 C# 的高级知识。所以看起来我确实在要求一个完整的解决方案。

c# multithreading .net-core

3
推荐指数
1
解决办法
1994
查看次数

使用c#中的线程用随机数填充数组

所以正如在 tile 中所说,我正在尝试使用 16 个(在我的情况下)线程用随机数填充一个字节数组,现在使用一个线程填充一个包含 500000000 个字节的数组大约需要六秒半的时间,所以逻辑上说,使用 16 个线程至少会快 10 倍,但后来我尝试这样做,花了 15 秒来填充它,我所做的是给每个线程一个段来填充相同的数组

这是代码:

        static byte[] nums2 = new byte[500000000];
        static Random rnd = new Random(123);
        static void fill()
        {
            for (int i = 0; i < nums.Length; i++)
                nums[i] = (byte)rnd.Next(10);
        }

        static void fillPart(object ID)
        {
            var part = nums2.Length / Environment.ProcessorCount;
            int baseN = (int)ID * part;
            for (int i = baseN; i < baseN + part; i++)
                nums2[i] = (byte)rnd.Next(10);
            Console.WriteLine("Done! " + ID);
        }

        static …
Run Code Online (Sandbox Code Playgroud)

c# arrays random multithreading thread-safety

3
推荐指数
1
解决办法
127
查看次数

非线程安全会增加Multiply-with-Carry伪随机数生成器的随机性吗?

我正在阅读本节,最后一段说明示例代码不是线程安全的.我的问题是:这不会有助于增加其随机性(即如果多个线程同时执行这些行)?

c random algorithm

2
推荐指数
1
解决办法
120
查看次数

在c#中创建加密随机数的最快,线程安全的方法?

注意到在多线程上并行生成随机数时,加密随机数生成器不是线程安全的.使用的生成器RNGCryptoServiceProvider似乎重复了很长的随机位(128位).重现此代码的代码如下所示.

如果没有使用锁来保护对RNGCryptoServiceProvider实例的访问(这会杀死整个速度点),有没有人有更快的方法来生成加密随机数?

using System;
using System.Runtime.Caching;
using System.Security.Cryptography;
using System.Threading.Tasks;

namespace ParallelRandomness
{
    class Program
    {
        static void Main(string[] args)
        {
            var test = new Test();
            Console.Write("Serialized verion running ...  ");
            test.Run(false);
            Console.WriteLine();
            Console.Write("Parallelized verion running ...  ");
            test.Run(true);
            Console.WriteLine(Environment.NewLine + "Done.");
            Console.ReadLine();
        }
    }

    class Test
    {
        private readonly RNGCryptoServiceProvider _rng = new RNGCryptoServiceProvider();
        private readonly byte[] _randomBytes = new byte[128 / 8];
        private int collisionCount = 0;
        private readonly object collisionCountLock  = new object(); …
Run Code Online (Sandbox Code Playgroud)

c# random parallel-processing multithreading cryptography

2
推荐指数
1
解决办法
928
查看次数

如何实现线程安全的随机数

尝试找到并理解在 .NET Core 2.x 或更高版本中实现线程安全数字生成器的最佳方法

首先我发现了这个 - https://web.archive.org/web/20160326010328/http://blogs.msdn.com/b/pfxteam/archive/2009/02/19/9434171.aspx

读完后,我觉得有几个“好”的方法 -

  1. ThreadStatic Random实例,用全局随机实例来生成种子
  2. 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(); …
Run Code Online (Sandbox Code Playgroud)

c# random multithreading cryptography .net-core

2
推荐指数
1
解决办法
2351
查看次数

C#中OAuth随机数的线程安全随机数/字符串生成器

我一直在使用中发现的OAuthBase类这里我SSIS 2008 C#脚本组件(.NET 3.5).

它一直运行良好,但最近我遇到了问题,如果我在同一个数据流任务中执行多个脚本组件,使用上面的OAuthBase类中的GenerateNonce方法,我最终得到相同的随机数(随机数).

以下是生成nonce的OAuthBase类的摘录:

using System;
using System.Security.Cryptography;
using System.Collections.Generic;
using System.Text;
using System.Web;

namespace OAuth {
 public class OAuthBase {

    ....snip......

    protected Random random = new Random();

    public virtual string GenerateNonce() {
        // Just a simple implementation of a random number between 123400 and 9999999
        return random.Next(123400, 9999999).ToString();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

在每个脚本组件中,我使用此C#代码来启动类并生成一个nonce:

        OAuthBase oAuth = new OAuthBase();
        string nonce = oAuth.GenerateNonce();
Run Code Online (Sandbox Code Playgroud)

从我的搜索周围,我认为这与它不是线程安全有关?我不完全确定.

我只能在SSIS 2008中运行.NET 3.5,所以我知道在.NET 4.0中引入的一些我不能使用的新东西.

关于如何修改OAuthBase类和/或我的C#脚本组件代码的任何想法?

c# ssis script-component .net-3.5

1
推荐指数
1
解决办法
4436
查看次数