本篇博客针对EventLoop类做下小结。
博客代码来自于陈硕的muduo网络库,github地址https://github.com/chenshuo/muduo
学习笔记:
muduo网络库的线程类遵循one loop per thread。顾名思义每个线程只能有一个EventLoop对象,因此EventLoop独享的构造函数会检查当前线程是否已经创建了其它EventLoop对象,如果已经创建则终止程序。创建了EventLoop的线程就是IO线程,其主要功能是运行时间循环EventLoop::loop(),在该循环中调用Poller::poll()执行阻塞式等待监听事件的响应,执行对应的回调函数。EventLoop对象可以在多线程使用,但是它的某些成员函数只有在EventLoop的创建者线程使用才是线程安全的(避免race-condition),EventLoop通过将调用函数传入pendingFunctors_,利用wakeupFd_唤醒EventLoop的创建者线程通知它及时执行pendingFunctors_中的函数。
EventLoop.h
#ifndef MUDUO_NET_EVENTLOOP_H
#define MUDUO_NET_EVENTLOOP_H
#include <atomic>
#include <functional>
#include <vector>
#include <boost/any.hpp>
#include "muduo/base/Mutex.h"
#include "muduo/base/CurrentThread.h"
#include "muduo/base/Timestamp.h"
#include "muduo/net/Callbacks.h"
#include "muduo/net/TimerId.h"
namespace muduo
{
namespace net
{
class Channel;
class Poller;
class TimerQueue;
///
/// Reactor, at most one per thread.
///
/// This is an interface class, so don't expose too much details.
class EventLoop : noncopyable
{
public:
typedef std::function<void()> Functor;
EventLoop();
~EventLoop(); // force out-line dtor, for std::unique_ptr members.
///
/// Loops forever.
///
/// Must be called in the same thread as creation of the object.
///
void loop();
/// Quits loop.
///
/// This is not 100% thread safe, if you call through a raw pointer,
/// better to call through shared_ptr<EventLoop> for 100% safety.
void quit();
///
/// Time when poll returns, usually means data arrival.
///
Timestamp pollReturnTime() const { return pollReturnTime_; }
int64_t iteration() const { return iteration_; }
/// Runs callback immediately in the loop thread.
/// It wakes up the loop, and run the cb.
/// If in the same loop thread, cb is run within the function.
/// Safe to call from other threads.
void runInLoop(Functor cb);
/// Queues callback in the loop thread.
/// Runs after finish pooling.
/// Safe to call from other threads.
void queueInLoop(Functor cb);
size_t queueSize() const;
// timers
// 以下3个run函数是对定时器的使用
///
/// Runs callback at 'time'.
/// Safe to call from other threads.
///
TimerId runAt(Timestamp time, TimerCallback cb);
///
/// Runs callback after @