本文主要是介绍分配式调度器(Allocation Scheduler)-有锁与无锁实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
原文转自:http://www.tanjp.com (即时修正和更新)
分配式调度器(Allocation Scheduler)
N个业务系统生产作业加入到 1个分配队列里面,由 1个分配线程负责将队列中作业分配给 M个工作队列,每个工作队列对应 1个工作线程来消费作业。对分配队列的抢占为:N*1,对工作队列的抢占为1*1,也就是说总体队列的抢占为 N*1+1*1*M,也就是 N+M。
分配式调度,从作业生产到被消费完,经历了 push->pop->push->pop,相比抢占式调去,多出了中间的pop->push两个步骤,会有一定的消耗
push pop push pop
job 1 ---->| main main | ===== q1 > ##### thread 1
| queue thread | ===== q2 > ##### thread 2
job 2 ---->| ======> ##### | ===== q3 > ##### thread 3
| | ...
job N ---->| | ===== qM > ##### thread M
条件变量与互斥锁方案
当分配队列为空时,分配线程由条件变量触发挂起等待。当工作队列为空时,工作线程由条件变量触发挂起等待。有作业加入到分配队列时,条件变量会唤醒一个等待中的分配线程,取出作业并且挂起等待一个空闲的工作队列,然后加入到空闲工作队列中,条件变量还会继续唤醒该工作队列的工作线程,取出作业并执行。此时如果工作队列已经为空,还需通知分配线程,该工作队列为空闲状态。
[job] -> |
|-> [main] -> [busy work] -> done
[idle work] -> | |
|<-----------------------------------------|
此方案中的队列均为有界队列,也就是说有作业数量上限,可以避免在极端情况下,队列爆满导致暴内存的问题。部分实现代码如下:
class SingleScheduler : public SchedulerBase
{
public:// @pp_idle_threads, 主要用作通知当前线程是否空闲。explicit SingleScheduler(SafeQueue< SingleScheduler* > * pp_idle_threads = 0);~SingleScheduler();bool start() override;bool post(Task * pp_task) override;bool stop() override;
private:void loop_running();
private:std::thread
这篇关于分配式调度器(Allocation Scheduler)-有锁与无锁实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!