East - Coroutine Scheduler Module

调度器模块

单单一个协程发挥不了威力,我们需要管理起来,Scheduler就是用来调度协程的。
我们用一张图来理解协程调度器:

Scheduler

首先先搞清楚几个变量:

1
2
3
4
//当前线程的调度器,同一个调度器下的所有线程指向同一个调度器
static thread_local Scheduler* t_scheduler = nullptr;
//当前线程的调度协程,每个线程都独有一个,包括caller线程
static thread_local Fiber* t_scheduler_fiber = nullptr;

这两个变量都是thread_local也就是每个线程都有一个,
但是一个调度器创建出来的线程的t_scheduler都是指向创建他们的调度器。
而t_shceduler_fiber就是各个线程的主协程了,方便和任务协程做切换。

接着我们根据图来看调度器的运作方式:

1.构造Scheduler的时候根据参数创建线程池,每个线程的入口函数都是run

2.线程启动后,都会将线程本身的主协程设置成t_scheduler_fiber,然后互斥的从队列中取出任务执行,执行后再切换回调度协程执行下一个任务,如果当前没有任务可以执行,就切换成idle协程,由于idle协程目前循环判断调度器是否停止,不停止就切换回调度协程,所以如果没有任务就会一直循环知道满足stop的条件。

3.调度器stop时,如果创建scheduler的线程也参与到调度中来的话,就会执行一次run方法,将任务执行完毕。

此外,我们的协程是非对称协程,即caller和callee的关系是固定的,协程resume的时候切换的协程就是yield后返回的协程。
而对称协程在于协程调用和返回的地位是相等的,协程启动之后就和启动之前没关系了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
非对称协程:

Scheduler Fiber-1 Fiber-2
|
|----------------resume------------>|
| |
| |
|<----------------yield-------------|
|
|
|----resume---->|
| |
| |
|<----yield-----|



对称协程:
Scheduler Fiber-1 Fiber-2
|
|----resume--->|
| |
| |--------resume----->|
| |
| |
| |<-------yield-------|
| |
| |
|<----yield----|
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2015-2025 Xudong0722
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信