一次只执行几个线程



我正在编写一个程序,在这个程序中,我们不断地启动新的线程去执行一个工作。我们注意到,即使我们可能启动了10个线程,一次也只有3或4个线程在执行。为了测试它,我做了一个像这样的基本示例:

private void startThreads()
{
for (int i = 0; i < 100; i++)
{
//Task.Run(() => someThread());

//Thread t = new Thread(() => someThread());
//t.Start();

ThreadPool.QueueUserWorkItem(someThread);
}
}
private void someThread()
{
Thread.Sleep(1000);
}

简单的东西,对吗?代码创建了100个线程并开始执行…但一次只有3到4个。当它们完成后,下一个线程开始执行。我本以为它们几乎都是同时开始执行的。对于100个线程(每个线程都有1秒的睡眠时间),大约需要30秒才能完成所有线程。我本以为花的时间会比这短得多。

我试过使用Thread.Start,ThreadPool和任务,都给了我完全相同的结果。如果我使用ThreadPool并检查每次线程运行时可用的线程数,总是有>2000个可用的工作线程和1000个可用的异步线程。

我只是使用上面的代码作为测试,试图找出发生了什么。在实践中,代码会到处生成线程。程序的CPU使用率低于5%,但是因为线程执行不够快而变得非常慢。

是的,你可能只有几个线程在同一时间运行。这就是ThreadPool的工作原理。它不必同时运行所有的线程。它将快速地将它们排队,但是当每个线程运行时,将其留给ThreadPool来处理。

如果你想确保所有100个线程同时运行,你可以使用:

ThreadPool.SetMinThreads(100, 100);

例如,见下面的代码,这是没有线程池最小大小的结果: 没有MinThreads

internal void startThreads()
{
ThreadPool.GetMaxThreads(out int maxThread, out int completionPortThreads);
stopwatch.Start();
var result = Parallel.For(0, 20, (i) =>
{
ThreadPool.QueueUserWorkItem(someThread, i);
});
while (!result.IsCompleted) { }
Console.WriteLine("Queueing completed...");
}
private void someThread(Object stateInfo)
{
int threadNum = (int)stateInfo;
Console.WriteLine(threadNum + " started.");
Thread.Sleep(10);
Console.WriteLine(threadNum + " finnished.");
}

Result (No MinThreads)

9 started.
7 started.
11 started.
10 started.
1 finnished.
12 started.
9 finnished.
13 started.
2 finnished.
4 finnished.
15 started.
3 finnished.
8 finnished.
16 started.
10 finnished.
6 finnished.
19 started.
0 finnished.
14 started.
5 finnished.
7 finnished.
17 started.
18 started.
11 finnished.
与MinThreads

internal void startThreads()
{
ThreadPool.GetMaxThreads(out int maxThread, out int completionPortThreads);
ThreadPool.SetMinThreads(20, 20); // HERE <-------
stopwatch.Start();
var result = Parallel.For(0, 20, (i) =>
{
ThreadPool.QueueUserWorkItem(someThread, i);
});
while (!result.IsCompleted) { }
Console.WriteLine("Queueing completed...");
}
结果

...
7 started.
15 started.
9 started.
12 started.
17 started.
13 started.
16 started.
19 started.
18 started.
5 finnished.
3 finnished.
4 finnished.
6 finnished.
0 finnished.
14 finnished.
1 finnished.
10 finnished.
...

一个漂亮干净的设计。

最新更新