简体   繁体   English

为什么创建新线程昂贵?

[英]Why is creating a new thread expensive?

I read lots of .Net resources telling me that I should be using a thread pool thread rather than instantiating a new thread myself. 我读了很多.Net资源告诉我,我应该使用线程池线程,而不是自己实例化一个新线程。 They say you should do this because instantiating a new thread is an expensive operation. 他们说你应该这样做,因为实例化一个新线程是一项昂贵的操作。 What happens during thread creation that makes it an expensive operation? 在创建线程期间会发生什么变得昂贵的操作?

Everything is relative. 一切都是相对的。 Creating a new thread is expensive... relative to not creating one. 创建一个新线程是昂贵的...相对于不创建一个。 If you're not doing a lot of work per thread, the work involved in building and tearing down the threads can potentially make up a measurable portion of your cpu time. 如果你没有为每个线程做很多工作,那么构建和拆除线程所涉及的工作可能会构成你可测量的cpu时间的一部分。 But it's cheap relative to creating a new process, especially on Windows. 但相对于创建新流程而言,它相对便宜,特别是在Windows上。

It's also generally better to use the threadpool because it is tuned to help you avoid having too many threads active at once. 使用线程池通常也更好,因为它经过调整可以帮助您避免同时激活太多线程。 You rarely want more than a handful of threads active at one time, or you'll spend a lot of cpu time performing context-switches between them all. 您很少想要一次激活多个线程,或者您将花费大量的CPU时间在它们之间执行上下文切换。 Using the threadpool manages this for you, as additional requests are queued until a worker thread is ready. 使用线程池可以为您管理,因为其他请求将排队,直到工作线程准备就绪。

Each thread by default gets 1 MB of memory allocated. 默认情况下,每个线程分配1 MB内存。 That can quickly get expensive. 这很快就会变得昂贵。

There are a couple of factors. 有几个因素。 One that's been mentioned is memory for the stack. 已经提到过的是堆栈的内存。 Because stack memory is not handled by the normal GC allocator used for objects, creating a thread's stack and then abandoning it is very different from creating a megs worth of heap objects and abandoning them. 因为堆栈内存不是由用于对象的普通GC分配器处理的,所以创建线程的堆栈然后放弃它与创建一堆价值的堆对象并放弃它们是截然不同的。

Another factor not yet mentioned is the cost associated with things like threadstatic variables. 另一个尚未提及的因素是与线性静态变量相关的成本。 In some systems which require all thread-static variables a thread might use to be defined before the thread starts, starting a new thread would require initializing all thread-static variables. 在某些需要所有线程静态变量的系统中,线程可能会在线程启动之前定义,启动新线程需要初始化所有线程静态变量。 Because .net allows threads to dynamically add threadstatic variables, the data structures used are different. 因为.net允许线程动态添加线程静态变量,所以使用的数据结构是不同的。 Nonetheless, initializing such data structures when a thread starts is not free. 尽管如此,在线程启动时初始化此类数据结构并不是免费的。

Threadpool is not only about amortizing the cost of thread creation and destruction and not only about saving memory with less stacks. Threadpool不仅仅是分摊线程创建和销毁的成本,而且不仅仅是用较少的堆栈来节省内存。 The real benefit of it avoids having too many active threads at the same time, and minimizing context switches if you run server application. 它的真正好处是避免同时拥有太多活动线程,并在运行服务器应用程序时最小化上下文切换。 Even if you are not writing server application, threadpool just a nicer abstraction than thread - start async operation, get notification when finished, or execute a callback when finished, and let OS or runtime figure out how many threads to create. 即使您没有编写服务器应用程序,线程池也只是比线程更好的抽象 - 启动异步操作,完成时获取通知,或者在完成时执行回调,并让操作系统或运行时确定要创建的线程数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM