主从reactor架构
一般的一个网络IO库都是主从reactor模式,即主线程中有一个MainReactor,其负责监听ListenFd,当接受到新的用户连接时,返回的clientfd并不会加入的MainReacotr,而是在子线程(这里称为IO线程)中,创建一个新的event_loop(即从Reactor, subreacotr),将clientfd加入到此SubReactor中,这样的架构称为主从reactor架构。这里阐述从Reactor的设计思路。(Reactor即event_loop)
IOThread
每一个从Reactor都需要一个IOThread来运行, 在这个IOThread中,需要放置一个event_loop,
在IOThread的构造函数中,初始化这个event_loop,之后开启这个event_loop,让其陷入epoll_wait中,epoll_wait等待的fd即上述的clientfd。考虑epoll_wait会阻塞,如果在IOThread中直接开启event_loop,则会阻塞创建的IOThread的地方,当然调用者可以在一个新的线程中创建IOThread, 但这样多少不方便了。
所以在IOThread中,会创建一个子线程,在子线程中创建、开启event_loop,这样调用IOThread的地方就变成异步了,创建IOThread对象后就返回。
考虑线程同步原因,可能IOThread返回后,event_loop创建好,所以加入一个信号量,当event_loop创建好,IOThread对象才构建好,可以返回。
考虑event_loop有时需要我们自主的选择开启,在IOThread中加入一个start函数,调用start函数后even_loop才开始真正的进行事件监听,所以需要再添加一个信号量。
这里需要两个信号量,一个用来控制event_loop创建好后,IOThread对象构造完成,可以返回,一个用来控制开启event_loop循环。
IOThreadGroup
可预先创建好多个IOThread对象放入IOThreadGroup中,在IOThreadGroup内部创建一个vector对象,内部存如IOThread对象,提供一个getIOThread方法,当客户端连接,需要IOThread时,直接调用getIOThread方法,返回一个可用的IOThread对象,用来充当从reactor。
可参考代码:
https://github.com/LIMengjie1/rocketrpc/tree/main/rocket/net
其中io_thread.cpp 和io_thread_group.cpp