https://github.com/chenshuo/muduo
int main(int argc, char* argv[])
{
int numThreads = 0;
if (argc > 1)
{
benchmark = true;
Logger::setLogLevel(Logger::WARN);
numThreads = atoi(argv[1]);
}
EventLoop loop;
HttpServer server(&loop, InetAddress(8000), "dummy");
server.setHttpCallback(onRequest);
server.setThreadNum(numThreads);
server.start();
loop.loop();
}
对于one thread one loop而言,上面的所有操作无非是将socketfd的Channel加入EPollPoller::channels_中,以及将socketfd加入epoll监听集合中;
EventLoop::loop()作用是,EPollPoller 类的poll 函数会收集所有发生事件的socketfd 的Channel存于activeChannels_ 中,因为每一个socketfd 在对应的Channel 中会设置读/写/及错误发生时候的回调函数的;接着遍历收集到的activeChannels_ , 并执行每一个Channel 的handleEvent 进而去调用设置的回调函数;当别的类想异步执行某个函数时候只需要调用EventLoop::runInLoop(const Functor& cb)该函数里面会判断如果执行该函数的线程与主线程不同则利用往evtfd 中写个字符触发epoll , 继而doPendingFunctors();得到执行了,即会执行上层注册的函数cb。
PollPoller.h
// Copyright 2010, Shuo Chen. All rights reserved.
// http://code.google.com/p/muduo/
//
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.
// Author: Shuo Chen (chenshuo at chenshuo dot com)
//
// This is an internal header file, you should not include this.
#ifndef MUDUO_NET_POLLER_H
#define MUDUO_NET_POLLER_H
#include <vector>
#include <boost/noncopyable.hpp>
#include <muduo/base/Timestamp.h>
#include <muduo/net/EventLoop.h>
namespace muduo
{
namespace net
{
class Channel;
///
/// Base class for IO Multiplexing
///
/// This class doesn't own the Channel objects.
class Poller : boost::noncopyable
{
public:
typedef std::vector<Channel*> ChannelList;
Poller(EventLoop* loop);
virtual ~Poller();
/// Polls the I/O events.
/// Must be called in the loop thread.
virtual Timestamp poll(int timeoutMs, ChannelList* activeChannels) = 0;
/// Changes the interested I/O events.
/// Must be called in the loop thread.
virtual void updateChannel(Channel* channel) = 0;
/// Remove the channel, when it destructs.
/// Must be called in the loop thread.
virtual void removeChannel(Channel* channel) = 0;
static Poller* newDefaultPoller(EventLoop* loop);
void assertInLoopThread()
{
ownerLoop_->assertInLoopThread();
}
private:
EventLoop* ownerLoop_;
};
}
}
#endif // MUDUO_NET_POLLER_H
需要弄清楚下面几个类:
class Channel; /*一个fd,对应一个Channel,该Channel中会给fd注册读、写、错误发生时候的处理函数的*/
boost::noncopyable /*在子类没有重写拷贝构造和赋值重载时候,子类对象是不允许进行赋值或者调用子类拷贝构造的*/
EventLoop /*无限循环中当epoll_wait()返回时候,将所有的Channel收集并存于activeChannels_中,接着就是执行activeChannels_中的每个Channel->handleEvent(),而改函数中会调用该Channel类对象的函数即给fd注册读、写、错误发生的处理函数*/
Timestamp /*利用微秒获得时间的*/