muduo库的学习4---loop的基本设计---EventLoop细节

这里会忽略用于测试,判断当前线程,返回数据成员的函数,省略标志位成员变量。

不区分public与private。

class EventLoop
{
/**********Function Memeber**************/
typedef boost::function<void()> Functor;

EventLoop();
~EventLoop();

//general
void loop();
void quit();

//timers
void runAt(const Timestamp& time, const TimerCallback &cb);
void runAfter(double delay, const TimerCallback &cb);
void runEvery(double interval, const TimerCallback &cb);

//Channel
void updateChannel(Channel* channel);
void removeChannel(Channel* channel);

//wakeup
void wakeup();
void handleRead();

void runInLoop(const Functor& cb);
void queueInLoop(const Functor& cb);
void doPendingFunctors();

int createEventfd();

/*************Data Member********************/
typedef std::vector<Channel*> ChannelList;

//general
boost::scoped_ptr<Poller> poller;
boost::scoped_ptr<TimerQueue> timerQueue;

//channel
ChannelList activeChannels;
channel* currentActiveChannel;

//wakeup
int wakeupFd;
boost::scoped_ptr<Channel> wakeupChannel;

MutexLock mutex;
std::vector<Functor> pendingFunctors;

};


需要特别说明的就是有关wakeup的东西

(1)wakeupFd用createEventfd()建立

用于表示此loop的fd,并且为了放入poller,专门用一个wakeupChannel来作为watcher。

(2)这整个wakeup相关的data与function,目的就是能够在线程之间调配任务,且在不加锁的情况下保证线程安全性。

runInLoop()保证放入其中的callback函数都由IO线程(及loop所在线程)调用,因为其他的线程可以通过持有loop而调用runInLoop。

runInLoop()首先判断当前线程是否为IO线程

①如果是,则可以直接调用callback

②如果不是,通过调用queueInLoop(),将这个callback放入pendingFunctors这个vector中,然后调用wakeup()向wakeupFd代表的事件(IO线程)发送一个字节,将其唤醒。这样唤醒后,loop线程的loop()就会在处理的时候通过调用doPendingFunctors(),调用pendingFunctors里面的callback。

综上,通过①,②保证了放入runInLoop()的callback都是由IO线程调用的。

从而保证了不用锁线程安全性。

(3)最后省的mutex以及handleRead的作用

①mutex

作为开放给其他所有线程的数据结构,pendingFunctors,其他线程可以同时向这个vector里面通过runInLoop()增加callback,

为了确保并发安全性对它的操作加个锁就是了。

②handleRead

通过wakeup()告知IO线程有pendingFunctors需要处理了,是通过poll来实现通知的,poll会对所有发生了关注事件的channel遍历处理。

而我们的wakeupChannel专门是通过socket,write一个字节来通知的,这里你放进去的callback可以将其read了,使其wakeupFd状态重新被监听。

然而真正的处理pendingFunctors是放在处理完所有的的activechannel的callback之后再调用doPendingFunctors()来处理的(代码见EventLoop::loop())。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值