1、概述
EventLoop相当于Reactor模型的Reactor反应堆的角色
poller和epollpoller相当于是多路分发器的角色,掌控epoll的所有操作
如果我们设置了setthreadnumber的多线程的反应堆类型,mainreactor就是处理新用户的连接,相当于accept,拿到新用户通信的fd,把fd和fd感兴趣的事件打包成channel,然后唤醒某个工作线程workreactor(subreactor)(采用轮询的方式),每个工作线程代表一个Eventloop。每个工作线程subreactor的EventLoop都监听一组channel,每一组channel都得在自己的eventloop线程去执行。
mainreactor如何给subreactor发配新连接,所采用的负载算法是一个轮询操作
mainreactor和subreactor如果没有事件发生的话,他们loop所在的线程都是阻塞的。
假如现在mainreactor监听到一个新用户的连接,得到了表示新用户连接的fd,以及感兴趣的事件的channel,它把这个channel怎么扔给subreactor呢?如何叫醒subReactor?
统一事件源原理
在libevent库中,采用的是socketpair
创建了一个本地socket的数组,与管道不同的是,这2个socket都是可读可写的,不像管道只能一端读,一端写。双向通信的socket,采用的是网络通信的模式。效率不如下面的eventfd。
在muduo库中,采用的是linux内核提供的比较新的eventfd
看到wait/notify,就应该反应过来,这就是线程间的通信机制。
这个线程可以notify通知其他线程起来做事情。eventfd是系统API,在内核可以直接notify用户空间的应用程序,让它的线程起来做事情,效率高。
2、EventLoop.h
#pragma once
#include <functional>
#include <vector>
#include <atomic>
#include <memory>
#include <mutex>
#include "noncopyable.h"
#include "Timestamp.h"
#include "CurrentThread.h"
class Channel;
class Poller;
//时间循环类 主要包含了两个大模块 Channel Poller(epoll的抽象)
class EventLoop:noncopyable
{
public:
using Functor=st