为什么我的线程池的线程不会在同一时间完成
在主函数中,我写这篇文章的代码:为什么我的线程池的线程不会在同一时间完成
ThreadPool.SetMaxThreads(200, 200);
for (int i = 0; i < 100; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadWhichWillCallSQL_test), i);
Thread.Sleep(1);
}
和线程功能是象下面这样:
static public void ThreadWhichWillCallSQL_test(Object o1)
{
Thread.Sleep(5000);
Console.WriteLine(DateTime.Now.ToString());
return;
}
输出为:
5/25/2017 2:00:01 PM
5/25/2017 2:00:01 PM
5/25/2017 2:00:01 PM
5/25/2017 2:00:01 PM
5/25/2017 2:00:02 PM
5/25/2017 2:00:03 PM
5/25/2017 2:00:04 PM
5/25/2017 2:00:05 PM
5/25/2017 2:00:05 PM
5/25/2017 2:00:06 PM
5/25/2017 2:00:06 PM
5/25/2017 2:00:06 PM
5/25/2017 2:00:06 PM
5/25/2017 2:00:07 PM
5/25/2017 2:00:07 PM
5/25/2017 2:00:08 PM
5/25/2017 2:00:08 PM
5/25/2017 2:00:09 PM
5/25/2017 2:00:09 PM
5/25/2017 2:00:10 PM
5/25/2017 2:00:10 PM
5/25/2017 2:00:10 PM
5/25/2017 2:00:11 PM
5/25/2017 2:00:11 PM
5/25/2017 2:00:11 PM
5/25/2017 2:00:11 PM
5/25/2017 2:00:12 PM
5/25/2017 2:00:12 PM
5/25/2017 2:00:12 PM
5/25/2017 2:00:13 PM
5/25/2017 2:00:13 PM
5/25/2017 2:00:13 PM
5/25/2017 2:00:14 PM
5/25/2017 2:00:14 PM
5/25/2017 2:00:14 PM
5/25/2017 2:00:15 PM
5/25/2017 2:00:15 PM
5/25/2017 2:00:15 PM
5/25/2017 2:00:15 PM
5/25/2017 2:00:16 PM
5/25/2017 2:00:16 PM
5/25/2017 2:00:16 PM
5/25/2017 2:00:16 PM
5/25/2017 2:00:17 PM
5/25/2017 2:00:17 PM
5/25/2017 2:00:17 PM
5/25/2017 2:00:17 PM
5/25/2017 2:00:18 PM
5/25/2017 2:00:18 PM
5/25/2017 2:00:18 PM
5/25/2017 2:00:18 PM
5/25/2017 2:00:19 PM
5/25/2017 2:00:19 PM
5/25/2017 2:00:19 PM
5/25/2017 2:00:19 PM
5/25/2017 2:00:20 PM
5/25/2017 2:00:20 PM
5/25/2017 2:00:20 PM
5/25/2017 2:00:20 PM
5/25/2017 2:00:20 PM
5/25/2017 2:00:21 PM
5/25/2017 2:00:21 PM
5/25/2017 2:00:21 PM
5/25/2017 2:00:21 PM
5/25/2017 2:00:22 PM
5/25/2017 2:00:22 PM
5/25/2017 2:00:22 PM
5/25/2017 2:00:22 PM
5/25/2017 2:00:22 PM
5/25/2017 2:00:23 PM
5/25/2017 2:00:23 PM
5/25/2017 2:00:23 PM
5/25/2017 2:00:23 PM
5/25/2017 2:00:23 PM
5/25/2017 2:00:24 PM
5/25/2017 2:00:24 PM
5/25/2017 2:00:24 PM
5/25/2017 2:00:24 PM
5/25/2017 2:00:24 PM
5/25/2017 2:00:25 PM
5/25/2017 2:00:25 PM
5/25/2017 2:00:25 PM
5/25/2017 2:00:25 PM
5/25/2017 2:00:25 PM
5/25/2017 2:00:25 PM
5/25/2017 2:00:26 PM
5/25/2017 2:00:26 PM
5/25/2017 2:00:26 PM
5/25/2017 2:00:26 PM
5/25/2017 2:00:27 PM
5/25/2017 2:00:27 PM
5/25/2017 2:00:27 PM
5/25/2017 2:00:27 PM
5/25/2017 2:00:27 PM
5/25/2017 2:00:27 PM
5/25/2017 2:00:28 PM
5/25/2017 2:00:28 PM
5/25/2017 2:00:28 PM
5/25/2017 2:00:28 PM
5/25/2017 2:00:28 PM
你可以注意到,所有线程完成的整个过程持续了将近28秒,从我的理解,这10个0线程也许不能同时完成,但也不能有那么多时间不同。
还我已成立
ThreadPool.SetMaxThreads(200, 200);
,并只分配100个线程,所以不应该有任何线程等待别人停下来,对不对?
这里是完整的代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace ThreadpoolDelay
{
class Program
{
static void Main(string[] args)
{
try
{
ThreadPool.SetMaxThreads(200, 200);
for (int i = 0; i < 30; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadWhichWillCallSQL_test), i);
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
public static void ThreadWhichWillCallSQL_test(Object o1)
{
Thread.Sleep(5000);
Console.WriteLine(DateTime.Now.ToString());
return;
}
}
}
线程不被在你的榜样,同时开始。添加以下调用后右SetMaxThreads
ThreadPool.SetMinThreads(200, 200);
这将使线程同时启动。这是关于ThreadPool线程创建机制的东西。我建议阅读ThreadPool documentation了解详情。
更恰当地对其进行调试,更新ThreadWhichWillCallSQL_test方法来添加启动时间太长:
static void ThreadWhichWillCallSQL_test(object o1)
{
Console.WriteLine("start:" + DateTime.Now);
Thread.Sleep(5000);
Console.WriteLine("finish: " + DateTime.Now);
}
令人惊叹的是,它作品。是的,我没有仔细阅读文档,只是复制并合并其他人的代码。谢谢 。 – yangl
很好的问题。
执行线程中的线程取决于许多因素,其中一个因素是cpu核心。它把线程运行在每个核心上,一旦完成,就把另一个核心运行起来。
例如:如果有4个核心cpu。它同时并行放置4个线程,然后在线程完成任务时放入下一个线程。机制就像那些不完全一样。 你还有5秒延迟(线程睡眠),所以 计算就像是如果有4个核心:(30线程/ 4核心)* 5有些不像那些。
还可以看到有更多的信息:https://msdn.microsoft.com/en-us/library/3dasc8as(v=vs.80).aspx
不是。池如何分配线程是一个实现细节,对于不同的版本它可能会有很大的不同。但合理的是,它不会为每个内核分配一个线程。 –
同意adrino但分配multipal线程到核心和切换它们之间的上下文 –
上下文切换?当然是。如果池为每个请求分配一个线程,那么总执行时间将约为5秒(忽略任何开销)。每个核心一个?它分配更多的线程,根据复杂的策略创建新的线程,直到最大OP集。短期生活操作的完美行为。当然,使用池分配30个长时间的延迟可以解决这个问题,但这只是人为的。 –
我的环境是的Visual Studio 2012和.NET Framework 4.5 – yangl
只能猜测,没有回答,没有好[mcve],可靠地再现问题。但是,'SetMaxThreads()'不会将新的活动线程添加到线程池中。它只是设置最大可能。因此,您仍然必须等待线程池被更多线程填充,因为您现有的工作项目需要很长时间。如果你运行两次测试会发生什么?它是否像你期待的那样第二次工作?为什么你甚至在乎?你真的有一个100核心机器? –
嗨,我没有100核心机器,但我的机器可以运行30个线程我想,当我使用30个线程进行测试时,最早的和最新的线程完成时间仍然有11秒不同,我已将完整的代码添加到此post – yangl