为什么某些线程池实现不使用生产者和使用者模型

why some thread pool implementation doesn't use producer and consumer model

本文关键字:生产者 使用者 模型 线程 实现 为什么      更新时间:2023-10-16

我打算实现一个线程池来管理我的项目中的线程。我想到的线程池的基本结构是队列,一些线程在这个队列中生成任务,一些由线程池管理的线程正在等待处理这些任务。我认为这是阶级生产者和消费者的问题。但是当我在网上搜索线程池实现时,我发现那些实现很少使用这个经典模型,所以我的问题是,为什么他们不使用这个经典的模型,这个模型有缺点吗?为什么他们不使用全信号量和空信号量进行同步?

如果有多个线程在一个资源上等待(在本例中是信号量和队列),则会造成瓶颈。即使您有多个工作人员,您也会强制所有任务通过一个队列。从逻辑上讲,如果工作人员通常处于空闲状态,这可能是有意义的,但线程池的全部目的是处理负载严重的场景,在这种场景中,工作人员保持忙碌(以获得最大吞吐量)。在多处理器系统中,使用单个输入队列会特别糟糕,因为在多处理器的系统中,所有工作人员在尝试获取下一个任务时都会读取和写入队列的头部。即使锁争用可能很低,每次更新队列头指针时,仍然需要将其从一个CPU缓存共享/通信到另一个CPU高速缓存。

想想理想的情况:所有的工人总是很忙。当新任务入队时,您希望将其分派给将首先完成其当前/挂起任务的工作者。

如果作为客户端,您有一个无争用预言机,它可以告诉您将新任务排入哪个工作线程,并且每个工作线程都有自己的队列,那么您可以用自己的多写器-单读器队列实现每个工作线程,并始终将新任务调度到最佳队列,从而消除单个共享输入队列上的工作线程争用。当然,您没有这样的预言机,但在工作人员用完任务或队列变得不平衡之前,这种机制仍然可以很好地工作。"窃取工作"处理这些情况,同时与单个队列的情况相比,仍然减少了争用。

另请参阅:窃取工作总是最合适的用户级线程调度算法吗?

为什么没有生产者和消费者模型实现

这个模型非常通用,可能有很多不同的解释,其中一个实现可能是Queue:

尝试Apache APR队列:

它被记录为Thread Safe FIFO bounded queue

http://apr.apache.org/docs/apr-util/1.3/apr__queue_8h.html