单线程reactor:
一般由一个event dispatche等待各类事件,而待事件发生后原地调用对应的event handler,全部调用后等待更多事件,故为loop。实质是把多段逻辑按事件触发顺序交织在一个系统线程中,一个even-loop只能使用一个核,故此类程序要么是IO-bound,要么是每个handler有确定的较短的运行时间,后则一个耗时漫长的回调会卡住整个程序。
N:1线程库(协程:即所有的协程运行于一个系统线程中,计算能力和各类eventloop库等价):
把N个用户线程映射入一个系统线程。同时只运行一个用户线程,调用阻塞函数时才会切换至其他用户线程。N:1线程库与单线程reactor在能力上等价,但事件回调被替换为上下文(栈、寄存器、signals),运行回调变成跳转至上下文
多线程reactor:
一般由一个或多个线程分别运行event dispatcher,待事件发生后把event handler 交给一个worker线程执行。这个模式是单线程reactor的自然扩展,可以利用多核。由于共用地址空间使得线程间交互变得廉价,worker thread间一般会更及时地均衡负载,而多进程一般依赖更的服务来分割流量,一个设计良好的多线程reactor程序往往比同一台机器上的单线程reactor进程更均匀地使用不同核心
M:N线程库:
把M个用户线程映射入N个系统线程。bthread是brpc使用的M:N线程库,指M个bthread会映射至N个pthread。pthread worker在任何时间只会运行一个bthread,当前bthread挂起时,pthread worker先尝试从本地runqueue弹出一个待运行的bthread,若没有,则随机偷另一个worker的待运行bthread,仍然没有才睡眠并会在有新的待运行bthread时被唤醒
多核扩展性:使用多任务队列,并调整调度算法以减少全局竞争,比如每个系统线程有独立的runqueue,由一个或多个scheduler把用户线程分发到不同的runqueue,每个系统线程优先运行自己runqueue中的用户线程,然后再考虑其他线程的runqueue