这是一个非常普遍的计算机科学问题,并不是特定于任何操作系统或框架。
所以我对与线程池上的切换任务相关的开销感到有些困惑。在许多情况下,为每个作业提供自己的特定线程没有意义(我们不想创建太多的硬件线程),因此我们将这些作业放入可以安排在线程上运行的任务中。我们建立了一个线程池,然后动态分配任务以在从线程池中获取的线程上运行。
我对与特定线程(在线程池中)切换任务相关的开销感到有点困惑(无法找到深入的答案)。 DrDobbs的一篇文章(摘自下文)表明它确实如此,但我需要更深入地回答实际发生的事情(一个可引用的来源会非常棒:))。
根据定义,SomeWork必须在池中排队,然后继续运行 与原始线程不同的线程。这意味着我们必然 排队开销加上一个上下文切换只是为了将工作移动到 游泳池。如果我们需要将答案传达回原文 线程,例如通过消息或Future或类似,我们将招致 另一个上下文切换。
来源:http://www.drdobbs.com/parallel/use-thread-pools-correctly-keep-tasks-sh/216500409?pgno=1
线程的哪些组件实际切换?线程本身实际上并没有切换,只是特定于线程的数据。与此相关的开销是多少(更多,更少或相同)?
答案 0 :(得分:4)
让我们在这里澄清前5个关键概念,然后讨论它们在线程池上下文中的关联:
主题: 在简短的简历中,它可以被描述为程序执行上下文,由正在运行的代码,cpu注册表和堆栈中的数据给出。创建线程时,会为其分配应在该线程上下文中执行的代码。在每个cpu周期中,线程都有一条指令要执行,并且cpu注册表中的数据和堆栈处于给定状态。
任务: 代表一个工作单元。它是分配给要执行的线程的代码。
上下文切换(来自维基百科): 是存储和恢复线程的状态(上下文)的过程,以便可以在以后从同一点恢复执行。这使得多个进程可以共享单个CPU,并且是多任务操作系统的基本特性。构成上下文的是上面解释的是正在执行的代码,cpu注册表和堆栈。
什么是上下文切换是线程。任务仅代表可以分配给要执行的线程的工作的和平。在给定时刻,线程可以执行任务。
线程池(来自维基百科): 在计算机编程中,线程池是创建许多线程以执行许多任务的地方,这些任务通常组织在队列中。
线程池队列: 将任务放置在池中的线程执行的位置。这种数据结构是内存的共享内容,线程可能会竞争排队/出队,可能导致高负载情况下的争用。
说明线程池使用方案:
操作系统可以随时停止线程的执行,上下文切换到另一个线程,返回后者继续停止。
当竞争cpus的活动线程数增加时,上下文切换的开销会增加。因此,理想情况下,线程池会尝试使用最少的必要线程占用计算机中所有可用的cpu。
如果您的任务没有代码阻塞某处,则上下文切换最小化,因为它不会使用比计算机上的可用cpus更多的线程。
当然,如果你只有一个核心,你的主线程和线程池将竞争相同的CPU。
答案 1 :(得分:0)
这篇文章可能会讨论将工作发布到池中并且正在等待它的结果的情况。通常在线程池上运行任务不会产生任何上下文切换开销。
想象一下排队1000个工作项。线程池线程将一个接一个地执行它们。所有这些都没有单一的上下文切换。
切换等待/阻止。