gpt4 book ai didi

c# - 为什么线程创建这么快?

转载 作者:太空宇宙 更新时间:2023-11-03 10:53:47 27 4
gpt4 key购买 nike

我在书中读到创建线程是昂贵的(不像进程创建那么昂贵,但仍然如此),我们应该避免它。我编写了测试代码,我对创建线程的速度感到震惊。

using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace ConsoleApplication1
{
class Program
{
static int testVal = 0;
static void Main(string[] args)
{
const int ThreadsCount = 10000;
var watch = Stopwatch.StartNew();
for (int i = 0; i < ThreadsCount; i++)
{
var myThread = new Thread(MainVoid);
myThread.Start();
}
watch.Stop();
Console.WriteLine("Test value ={0}", testVal);
Console.WriteLine("Ended in {0} miliseconds", watch.ElapsedMilliseconds);
Console.WriteLine("{0} miliseconds per thread ", (double)watch.ElapsedMilliseconds / ThreadsCount);
}

static void MainVoid()
{
Interlocked.Increment(ref testVal);
}
}
}

输出:

Test value =10000

Ended in 702 miliseconds

0,0702 miliseconds per thread.

是我的代码错了还是创建线程太快而书上的建议错了? (我只看到每个线程有一些额外的内存消耗,但没有创建时间。)

最佳答案

创建线程非常慢。考虑这段对比内联处理速度和多线程处理速度的代码:

private void DoStuff()
{
const int ThreadsCount = 10000;
var sw = Stopwatch.StartNew();
int testVal = 0;
for (int i = 0; i < ThreadsCount; ++i)
{
Interlocked.Increment(ref testVal);
}
sw.Stop();
Console.WriteLine(sw.ElapsedTicks);

sw = Stopwatch.StartNew();
testVal = 0;
for (int i = 0; i < ThreadsCount; ++i)
{
var myThread = new Thread(() =>
{
Interlocked.Increment(ref testVal);
});
myThread.Start();
}
sw.Stop();
Console.WriteLine(sw.ElapsedTicks);
}

在我的系统上,内联需要 200 个滴答。对于线程,它几乎是 200 万个滴答声。所以在这里使用线程大约需要 10,000 倍的时间。我在这里使用 ElapsedTicks 而不是 ElapsedMilliseconds,因为使用 ElapsedMilliseconds 时,内联代码的输出为 0。线程版本大约需要 700 毫秒。上下文切换很昂贵。

此外,您的测试存在根本性缺陷,因为您没有明确等待所有线程完成后再获取结果。很有可能您可以在最后一个线程完成递增之前输出 testVal 的值。

顺便说一句,在计时代码时,您应该确保在没有附加调试器的情况下以 Release模式运行它。在 Visual Studio 中,使用 Ctrl+F5(无需调试即可启动)。

关于c# - 为什么线程创建这么快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20293332/

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