《muduo网络库》学习笔记——EventLoop类剖析

目录

一:线程通信机制

二:EventLoop类的剖析

三:muduo跨线程函数调用


一:线程通信机制

通常一个进程(线程)通知另一个等待中的(线程),有以下几种方法:

  1. pipe,使用fd[0] 为读端,fd[1]为写端,半双工。等待线程关注fd[0]的可读事件。
  2. socketpair,也有一对文件描述符,可用于双向通信,全双工。
  3. eventfd。eventfd是一个比pipe更高效的线程间事件通知机制,一方面,它比 pipe少用一个pipe descriptor,节省了资源;另一方面,eventfd的缓冲区管理简单,全部“buffer"只有定长8bytes,不像pipe那样可能有不定长的真正buffer。
  4. condition。线程可以使用条件变量condition来实现消息通信。

muduo采用eventfd进行线程间通信,函数定义如下:

#include <sys/eventfd.h>
 
int eventfd(unsigned int initval, int flags);
  • 第一个参数是初始值,一般设置为0,后面是O_NONBLOCK、EFD_CLOEXEC之类的标志。

eventfd()创建了一个事件对象 (eventfd object), 能在用户态用做事件wait/notify机制,通过内核去唤醒用户态的事件。内核会为这个对象维护一个64位的计数器(uint64_t)。并且使用第一个参数(initval)初始化这个计数器。调用这个函数就会返回一个新的文件描述符(event object)。这个描述符支持 read,write,以及有关epoll等操作。

二:EventLoop类的剖析

EventLoop是整个muduo网络库的核心类,其重要性不言而喻,它的主要成员如下:

typedef std::vector<Channel*> ChannelList;
 
bool looping_; /* atomic */    //loop循环标志
bool quit_; /* atomic and shared between threads, okay on x86, I guess. */   //是否退出标志
bool eventHandling_; /* atomic */     //是否在处理事件标志
bool callingPendingFunctors_; /* atomic */   //是否调用pendingFunctors标志
int64_t iteration_;       //迭代器,记录loop函数循环的次数
const pid_t threadId_;   //当前所属对象线程id
Timestamp pollReturnTime_;    //时间戳,poll返回的时间戳
boost::scoped_ptr<Poller> poller_;  //poller对象
boost::scoped_ptr<TimerQueue> timerQueue_;    //TimerQueue类型对象指针,构造函数中new
int wakeupFd_;     		//用于eventfd,线程间通信
// unlike in TimerQueue, which is an internal class,
// we don't expose Channel to client.
boost::scoped_ptr<Channel> wakeupChannel_;   //wakeupfd所对应的通道,该通道会纳入到poller来管理
boost::any context_;    //暂未剖析
 
// scratch variables
ChannelList activeChannels_;   //Poller返回的活动通道,vector<channel*>类型
Channel* currentActiveChannel_;   //当前正在处理的活动通道
 
MutexLock mutex_;
std::vector<Functor> pendingFunctors_; // GuardedBy mutex_ //本线程或其它线程使用queueInLoop添加的任务,可能是I/O计算任务

下面是它的构造函数:

EventLoop::EventLoop()
  : looping_(false),  //表示还未循环
    quit_(false),
    eventHandling_(false),
    callingPendingFunctors_(false),
    iteration_(0),
    threadId_(CurrentThread::tid()),   //赋值真实id
    poller_(Poller::newDefaultPoller(this)),   //构造了一个实际的poller对象
    timerQueue_(new TimerQueue(this)),   //构造一个timerQueue指针,使用scope_ptr管理
    wakeupFd_(createEventfd()),   //创建eventfd作为线程间等待/通知机制
    wakeupChannel_(new Channel(this, wakeupFd_)),   //创建wakeupChannel通道,
    currentActiveChannel_(NULL)
{
  LOG_DEBUG << "EventLoop created " << this << " in thread " << threadId_;
  if 
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值