gpt4 book ai didi

c# - 了解 Parallel.For 循环和局部变量

转载 作者:太空宇宙 更新时间:2023-11-03 18:51:08 25 4
gpt4 key购买 nike

我是并行计算的新手,在 C# 中运行 Parallel.For 时遇到了一些问题。我正在尝试同时访问多个网站,获取 HTML 并将它们注册到多个 SQLite 数据库中。在我更精确地检查结果之前,一切似乎都很好。我注意到在一个 0 到 20 的循环中,代码在循环的共享部分输入了 20 次,而在本地部分只输入了 16 次。因此,缺少 4 个结果。为了理解这个问题,我做了一个只放两个计数器的经历。一个在全局部分,另一个在本地。全局计数的输出是 20,在本地部分是 1!之后我在全局部分返回到本地部分之前睡了 2 秒。在这种情况下,全局计数的输出是 20,而本地部分是 13!你能解释一下我做错了什么吗?

static void ParalellCalc()
{
var tm = new Stopwatch();
tm.Start();
int count = 0;
int count2 = 0;
var parl = Parallel.For<int>(0, 20, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount}, () => 0, (i, state, Enrada) =>
{
count++;
Thread.Sleep(2000);
return Enrada;
},
(x) =>
{
count2++;
}
);

tm.Stop();
Console.WriteLine(tm.Elapsed);
Console.WriteLine("Global: " + count.ToString());
Console.WriteLine("Local: " + count2.ToString());
Console.WriteLine(tm.Elapsed);
tm.Reset();
}

编辑:我听取了你的建议,并用 Interlocked.Increment 做了同样的例子来增加计数器。产生的结果完全相同。如果我删除 Thread.Sleep(2000),第二个计数器会产生 1 的结果!?如果我不删除产生 16 的结果。第一个计数器在所有情况下显示 20 的值应该是。谁能解释一下?

static void ParalellCalc()
{
var tm = new Stopwatch();
tm.Start();
int count = 0;
int count2 = 0;
var parl = Parallel.For<int>(0, 20, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount}, () => 0, (i, state, Enrada) =>
{
Interlocked.Increment(ref count);
return Enrada;
},
(x) =>
{
Interlocked.Increment(ref count2);
});

tm.Stop();
Console.WriteLine(tm.Elapsed);
Console.WriteLine("Global: " + count.ToString());
Console.WriteLine("Local: " + count2.ToString());
Console.WriteLine(tm.Elapsed);
tm.Reset();
}

最佳答案

++ 运算符不是线程安全的,因为它不是原子的。 Interlocked.Increment是线程安全的。 Interlocked.Increment(ref count) 而不是 count++ 并且 count2 可能会修复计数。

关于c# - 了解 Parallel.For 循环和局部变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59204029/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com