...
Graphviz | ||
---|---|---|
| ||
digraph { rankdir=LR; node [style=filled]; compound=true; subgraph sub1 { start [label="main函数开始" shape=none style=""]; main1 [label = "创建调度器"]; main2 [label = "开始调度"]; main3 [label = "添加调度任务"]; main4 [label = <停止调度<BR/>(等待调度线程退出)>]; end [label="main函数结束" shape=none style=""]; rank=same; start -> main1 -> main2 -> main3 -> main4 -> end; } subgraph sbu2 { scheduler1 [label="调度协程" style=filled]; scheduler2 [label="调度协程" style=filled]; scheduler3 [label="调度协程" style=filled]; scheduler4 [label="调度协程" style=filled] scheduler_end [label="结束调度线程结束"] child1 [label="子协程1"] child2 [label="子协程2"] child3 [label="子协程3"] {rank=same; scheduler1 scheduler2 scheduler3 scheduler4 scheduler_end} {rank=same; child1 child2 child3} } scheduler1->child1->scheduler2->child2->scheduler3->child3->scheduler4->scheduler_end; main2->scheduler1[label="创建调度线程"]; } |
...
Graphviz | ||
---|---|---|
| ||
digraph {
rankdir=LR;
node [style=filled];
compound=true;
subgraph sub1 {
start [label="main函数开始" shape=none style=""];
main1 [label = "创建调度器"];
main2 [label = <开始调度<BR/>(实际什么也没做)>];
main3 [label = "添加调度任务"];
main4 [label = <停止调度<BR/>>];
end [label="main函数结束" shape=none style=""];
rank=same;
start -> main1 -> main2 -> main3 -> main4 -> end;
}
subgraph sbu2 {
scheduler1 [label="调度协程" style=filled];
scheduler2 [label="调度协程" style=filled];
scheduler3 [label="调度协程" style=filled];
scheduler4 [label="调度协程" style=filled]
child1 [label="子协程1"]
child2 [label="子协程2"]
child3 [label="子协程3"]
{rank=same; scheduler1 scheduler2 scheduler3 scheduler4}
{rank=same; child1 child2 child3}
}
scheduler1->child1->scheduler2->child2->scheduler3->child3->scheduler4;
main4 -> scheduler1 [label="切到调度协程"];
scheduler4 -> main4 [label=<全部任务执行结束后<BR/>调度协程返回main函数主协程>];
} |
然而,回顾一下前面协程模块就会发现,上面这种协程切换实际是有问题的,参考下面这张图:
Graphviz | ||
---|---|---|
| ||
digraph asymmetric_fiber { rankdir=LR; start [label="开始" shape=none style=""]; main1 [label = "主协程" style=filled]; main2 [label = "主协程" style=filled]; main3 [label = "主协程" style=filled]; main4 [label = "主协程" style=filled]; end [label="结束" shape=none style=""]; {rank=same; start main1 main2 main3 main4 end;} sub1 [label="子协程1"]; sub2 [label="子协程2"]; sub3 [label="子协程3"]; sub5 [label="子协程5"]; {rank=same; sub1 sub2 sub3 sub5;} sub4 [label="子协程4"]; sub6 [label="子协程6"]; {rank=same; sub4 sub6;} start -> main1; main1 -> sub1; sub1 -> main2; main2 -> sub2; sub2 -> main3; main3 -> sub3; sub3 -> sub4; sub4 -> sub5; sub5 -> sub6; sub6 -> main4 [label="无法切回主协程" style=dotted]; main4 -> end; } |
在非对称协程里,子协程只能和线程主协程切换,而不能和另一个子协程切换。在上面的情况1中,线程主协程是main函数对应的协程,另外的两类协程,也就是调度协程和任务协程,都是子协程,但
sylar协程模块运行图示
然后描述一下协程调度的本质。
...