C# 为什么我的线程池';s线程不会同时完成
在main函数中,我编写以下代码:C# 为什么我的线程池';s线程不会同时完成,c#,multithreading,threadpool,thread-sleep,queueuserworkitem,C#,Multithreading,Threadpool,Thread Sleep,Queueuserworkitem,在main函数中,我编写以下代码: ThreadPool.SetMaxThreads(200, 200); for (int i = 0; i < 100; i++) { ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadWhichWillCallSQL_test), i); Thread.Sleep(1); }
ThreadPool.SetMaxThreads(200, 200);
for (int i = 0; i < 100; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadWhichWillCallSQL_test), i);
Thread.Sleep(1);
}
输出为:
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秒,从我的理解,这100个线程也许不能同时完成,但也不能有那么多时间不同
我还设置了
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;
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用系统线程;
命名空间线程池延迟
{
班级计划
{
静态void Main(字符串[]参数)
{
尝试
{
SetMaxThreads(200200);
对于(int i=0;i<30;i++)
{
QueueUserWorkItem(新的WaitCallback(ThreadWhichWillCallSQL_测试),i);
}
}
捕获(例外e)
{
Console.WriteLine(如ToString());
}
Console.WriteLine(“\n按ENTER继续…”);
Console.Read();
}
将调用SQL\U测试的公共静态无效线程(对象o1)
{
睡眠(5000);
Console.WriteLine(DateTime.Now.ToString());
返回;
}
}
}
问得好
线程拉取中线程的执行取决于许多因素,其中一个因素是cpu核心。它将线程放在每个内核中运行,完成后再放另一个
示例:如果有4个核心cpu。它同时并行放置4个线程,然后在线程完成任务时放置下一个线程。机制是这样的,不完全是这样的。
此外,你还把有5秒的延迟(线程睡眠)所以
计算就像有4个核心:(30个线程/4个核心)*5个类似的核心,但不完全是这些核心
您还可以在此处查看更多信息:在您的示例中,线程不是同时启动的。在SetMaxThreads之后添加以下调用 这将使线程同时启动。这是关于线程池线程创建机制的内容。我建议详细阅读 要更正确地调试,请更新线程,该线程将调用SQL\u测试方法以添加开始时间:
static void ThreadWhichWillCallSQL_test(object o1)
{
Console.WriteLine("start:" + DateTime.Now);
Thread.Sleep(5000);
Console.WriteLine("finish: " + DateTime.Now);
}
我的环境是Visual studio 2012和.net FrameWork 4.5,如果没有可靠地再现问题的良好工具,人们只能猜测,不能回答。但是,
SetMaxThreads()
不会向线程池添加新的活动线程。它只是设置了可能的最大值。因此,您仍然必须等待线程池中填充更多线程,因为现有工作项花费的时间太长。如果运行两次测试会发生什么?它是否像你第二次期望的那样工作?你为什么这么在乎?你真的有100核的机器吗?嗨,我没有100核的机器,但是我的机器可以运行30个线程,我想,当我使用30个线程进行测试时,最早和最晚的线程完成时间仍然有11秒的不同,我已经在这篇文章中添加了完整的代码作为问题/答案指出,你看错了方向。这并不是说他们没有在同一时间结束。这是因为线程池需要时间向池中添加更多线程。所以它们不是在同一时间开始的。不是真的。池如何分配线程是一个实现细节,对于不同的版本可能会有所不同。然而,它并没有为每个核心分配一个线程,而是为核心分配多线程,并在上下文切换之间切换上下文?当然可以。若池为每个请求分配一个线程,那个么总执行时间大约为5秒(忽略任何开销)。每个核心一个?它分配更多的线程,在需要时根据复杂的策略创建新线程,直到最大操作集。短命手术的完美行为。当然,使用池来分配30个长延迟会利用这个问题,但这只是人为的。当一个线程睡眠时,同一个内核会被许多其他线程使用(这是一个在亲和性、有利于缓存和保持所有内核忙碌、有利于并行性之间的折衷),感谢Adriano Repetti的精彩解释,它起作用了。是的,我没有认真阅读文档,只是复制并合并其他人的代码。非常感谢。
ThreadPool.SetMinThreads(200, 200);
static void ThreadWhichWillCallSQL_test(object o1)
{
Console.WriteLine("start:" + DateTime.Now);
Thread.Sleep(5000);
Console.WriteLine("finish: " + DateTime.Now);
}