在 C# 池线程中休眠
在这个有关 C# 线程的网络教程中,Joseph Albahari 写道:“别去睡觉在池线程中!”为什么你不应该这样做?它对性能的影响有多严重? (并不是我想这么做,我只是好奇。)
In this web tutorial on threading in C#, Joseph Albahari writes: "Don't go sleeping in pooled threads!" Why should you not do this? How badly can it affect performance? (It's not that I want to do it; I'm just curious.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
线程池中的线程数量有限;线程池旨在有效地执行大量短任务。它们依赖于每个任务快速完成,以便线程可以返回池并用于下一个任务。
因此,在线程池中休眠的线程会导致池耗尽,最终可能会耗尽可用线程,并且无法处理您分配给它的任务。
There are only a limited number of threads in the thread pool; thread pools are designed to efficiently execute a large number of short tasks. They rely on each task finishing quickly, so that the thread can return to the pool and be used for the next task.
So sleeping in a thread pool thread starves out the pool, which may eventually run out of available threads, and be unable to process the tasks you assign to it.
线程池的目的是在不同的线程上快速完成相对较短的任务,而无需花费创建新线程的成本。线程池具有最大线程数,一旦达到该上限,任务就会排队,直到有线程可用。
因此,在线程池上休眠的线程会占用队列,或者导致线程池耗尽。
The thread pool is meant to quickly do a relatively short task on a different thread without having to spend the cost of creating a new thread. The thread pool has a maximum number of threads, and once that is reached, tasks are queued until a thread becomes available.
A thread sleeping on the thread pool would therefore hold up the queue, or contribute to thread pool exhaustion.
线程是一个重量级对象。
创建一个新线程需要大量资源,例如为托管堆栈分配 1 MB、创建托管线程对象、内核堆栈、内核线程对象、用户线程环境块。这一切都需要时间和记忆。因此,您不想很快地创建和销毁对象。此外,一旦有多个线程,上下文切换也会占用一些资源
线程池是 CLR 可以放置未使用线程的地方,以防您的应用程序需要它。
线程池最初包含 0线程,一旦您从池中请求线程,池将快速创建为池定义的最小数量的线程。大约 2 分钟后,未使用的线程将被杀死。但如果负载增加并且需要更多线程,线程池将慢慢创建新线程,直到达到最大界限。线程数不能超过最大数量,一旦工作线程返回到池中,所有新请求都将排队并执行。在最坏的情况下,您可能会得到 OutOfMemoryException
如果从池中获取的线程被阻塞,它:
Thread is a heavy-weight object.
Creating a new thread requires lots of resources, such as assigning 1 MB for a managed stack, creating managed thread object, kernel stack, kernel thread object, user thread environment block. This all takes time and memory. Therefore you do not want to create and destroy objects really quickly. Furthermore, once you have more than one thread context switching will take some resources as well
Thread pool is a place where CLR can put unused threads, in case your application needs it.
Threadpool initially contains 0 threads, once you request a thread from a pool, the pool will quickly create the minimum number of threads defined for the pool. After around 2 minutes unused threads get killed. But if the load increases and you need more threads, thread pool will slowly create new threads until the maximum bound reached. You cannot have more threads than maximum, all new requests will be queued and executed once a working thread returned to the pool. In worse case scenario you can get OutOfMemoryException
If a thread taken from a pool is blocked, it: