Multithreading 如果每个线程执行一系列任务,或者多组线程每个执行一个任务,那么设计多线程程序通常更好吗?

Multithreading 如果每个线程执行一系列任务,或者多组线程每个执行一个任务,那么设计多线程程序通常更好吗?,multithreading,Multithreading,假设程序1有N个线程,其中每个线程依次执行任务A、任务B和任务C 程序2有3个由N个线程组成的线程池,每个线程池只执行一个任务,每个任务完成后,使用线程安全队列/对象将其传递给另一个线程池中的线程 在设计和/或性能方面,哪一个通常更好?这是一个相当复杂的问题 就吞吐量而言,当系统处于负载状态时,这两种方法的性能通常大致相同。如果您想最大限度地提高吞吐量,您只需确保所有核心都在忙着做需要做的工作,并且这两种设计都可以 就延迟而言(每个ABC序列所需的挂钟时间),在整个序列中使用一个线程有时可以执行

假设程序1有N个线程,其中每个线程依次执行任务A、任务B和任务C

程序2有3个由N个线程组成的线程池,每个线程池只执行一个任务,每个任务完成后,使用线程安全队列/对象将其传递给另一个线程池中的线程


在设计和/或性能方面,哪一个通常更好?这是一个相当复杂的问题

就吞吐量而言,当系统处于负载状态时,这两种方法的性能通常大致相同。如果您想最大限度地提高吞吐量,您只需确保所有核心都在忙着做需要做的工作,并且这两种设计都可以

就延迟而言(每个ABC序列所需的挂钟时间),在整个序列中使用一个线程有时可以执行得更好。当1线程完成其A时,它几乎总是立即开始执行B。如果它将B转移到另一个线程池,那么在B池中的某个线程将其接收并开始处理之前,通常会有一些不确定的延迟。同样,这只是系统处于压力之下时的问题。。。但如果没有压力,那也没关系

在设计方面,存在权衡。选项1很容易找到正确的答案。如果您使用相同的资源(相同的线程总数),那么使用简单的方法将在许多类型的作业中表现良好

选项2(多个池)需要做更多的工作,因为您必须控制每个队列的长度。如果已经有很多东西在等待B,那么您现在还不想再接下去,因为您应该使用这些核心来降低B的延迟,等等。不过,对于某些类型的作业,此控件是有用的。例如,如果所有的B都争用一个公共I/O资源,那么不管怎样,让一大堆线程执行B可能没有意义,因为除了一个或两个线程之外,所有线程都将始终被阻塞。在这种情况下,选项2将有更少的线程堆栈在内存中无所事事,更少的线程争夺稀缺资源(争用成本周期),等等

一般来说,我会在大多数情况下使用选项1。选项2只有在您需要对调度进行复杂控制时才真正有用

但请注意:这些选项并不是相互排斥的。即使在选项2中,每个“任务”也会分解为更小的任务,因此我们真正要讨论的是何时将某些任务交给另一个线程池。当您需要不同数量的线程来执行每个任务时,您可以这样做,而当有一些任务会导致太多线程相互争夺资源或挂起阻塞时,通常会发生这种情况