什么是线程池?


62

一个人如何实现线程池?我一直在Wikipedia上阅读“线程池”,但是我仍然想不出该解决该问题的方法(可能是因为我不太了解简单的线程池)。

有人可以用简单的英语解释我是什么线程池,一个人将如何回答这个问题?

Answers:


96

线程池是一组预先实例化的空闲线程,它们随时可以进行工作。当要执行大量的短任务而不是少量的长任务时,这些优先于为每个任务实例化新线程。这样可以避免产生大量线程的开销。

实施会因环境而异,但简单来说,您需要以下内容:

  • 一种创建线程并使它们保持空闲状态的方法。这可以通过让每个线程在屏障处等待直到池将其交给工作来实现。(这也可以用互斥锁完成。)
  • 一个用于存储创建的线程的容器,例如队列或任何其他可以将线程添加到池中并拉出线程的结构。
  • 线程在工作中使用的标准接口或抽象类。这可能是一种叫做抽象类Taskexecute()该做的工作,然后返回方法。

创建线程池时,它将实例化一定数量的线程以使其可用或根据实现的需要根据需要创建新的线程。

将池移交给a时Task,它将从容器中获取一个线程(如果容器为空,则等待一个线程可用),将其移交给a Task,并遇到障碍。这将导致空闲线程恢复执行,并调用给定的execute()方法Task。执行完成后,线程将自己移回池中以放入容器中以供重用,然后遇到其障碍,使自己进入睡眠状态,直到循环重复。


19
线程池是一组预先实例化的空闲线程,它们随时可以进行工作。[...]这样可以避免产生大量线程的开销。-每当有人搜索“线程池”时,Google都应该吐出
Rafael Eyng 2015年

线程池创建是否在 内部涉及障碍?您可以在这些行上共享参考吗?
外汇兑换交易'17年

@overexchange不,不是。我对这个问题的引用是重新编写障碍问题的一种更好方法的示例。(如果您愿意,我会写一个答案。)
Blrfl

最好的简短答案之一。
Blood-HaZaRd

10

线程池是通常在队列中组织的托管线程的集合,这些托管线程执行任务队列中的任务。

每当您需要异步执行某些操作时,创建一个新的线程对象都是很昂贵的。在线程池中,您只需将希望异步执行的任务添加到任务队列中,线程池就负责为相应任务分配可用线程(如果有)。任务完成后,现在可用的线程将请求另一个任务(假设还有剩余的任务)。

线程池可帮助您避免创建或破坏超出实际需要的线程。

我将从创建带有线程队列和任务队列的类开始。然后实现将任务添加到任务队列并从那里继续前进的方法。显然,您还应该可以在线程池中设置允许的最大线程数。


1

在多线程应用程序中,线程池是您的应用程序可以使用的“可用线程池”。通常,例如.NET都是托管的,因此您只需分配任务即可,一旦线程空闲,它将执行该任务。因此,要实现线程池,我希望创建一个概念,其中空闲线程自动执行任务,而无需为每个任务显式创建线程。


1

现实生活中的例子;

  1. 设施:操作系统
  2. 章节:应用
  3. 人物:线程

您有一个设施,那里有12个人在工作。该设施共有3个部分。厨房,洗手间和安全性。如果您不使用线程池技术,那么它就是这样工作的:所有12个人都将站在会议室中,如果新客户来自设施并要求任务,那么您将把人们分成几组并派他们去做,然后回到会议室。但是,在他们上班之前,有一个准备阶段。他们需要穿着正确的制服,装备某些设备,然后步行到该区域,完成工作并返回。因此,每次他们完成工作(线程结束)后,就需要回到会议室,脱下制服,取出设备并等待下一份工作。这些指的是创建线程上下文,它是操作系统的内存分配和跟踪信息。

如果使用线程池,那么在清晨,您将为厨房分配6个人,为卫生间分配2个人,为安全分配4个人。因此,他们每天只会做一次准备。即使厨房里没有顾客,那四个人也将在那里闲着,等待即将到来的任务。在厨房关闭(应用结束)之前,他们不需要回到会议室。这4个人位于Kitchen应用程序池中,可以快速提供服务。但是,您不能保证他们会整天工作,因为厨房可能会不时变得闲置。同样的逻辑也适用于洗手间和安全性。

在第一种情况下,您不会为任何任务浪费任何线程,但是为每个任务准备每个线程将花费大量时间。在第二篇文章中,您预先准备了线程,因此您不能保证将所有线程都用于所有任务,但是OS在很大程度上对其进行了优化,因此您可以放心地依赖它。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.