Muduo 库快速上手
一.Muduo 库简介
一句话概括,Muduo 库是基于非阻塞 IO 和事件驱动的 C++ 高并发 TCP 网络编程库。使用主从 Reactor 模型,使用的线程模型是是 one thread one loop
- Reactor:基于事件触发的模型(基于 epoll 进行 IO 事件监控)
- 主从 Reactor:将 IO 事件监控进一步划分,主 Reactor 线程只监控新建连接的事件,一旦连接事件触发,就会读取连接,然后执行回调函数;从 Reactor 线程针对新建连接进行 IO 事件监控,一旦 IO 事件触发,就会执行 IO 操作以及业务处理(我们设置的回调函数)。
- one thread one loop:一个线程只能有一个事件循环(EventLoop 对象),用于响应计时器和和 IO 事件
- 一个文件描述符只能由一个线程进行读写,换句话说一个 TCP 连接必须由某个 EventLoop 对象管理
二.五个常用类介绍
muduo::net::TcpServer:通常由服务端主线程调用其 start 接口,监听端口。通常需要配合 EventLoop 对象使用,循环地监控新建连接事件
typedef std::shared_ptr<TcpConnection> TcpConnectionPtr;
typedef std::function<void(const TcpConnectionPtr &)> ConnectionCallback;
typedef std::function<void(const TcpConnectionPtr &,Buffer *, Timestamp)> MessageCallback;
class InetAddress : public muduo::copyable
{
public:
InetAddress(StringArg ip, uint16_t port, bool ipv6 = false);
};
class TcpServer : noncopyable
{
public:
enum Option
{
kNoReusePort,
kReusePort,
};
TcpServer(EventLoop *loop,
const InetAddress &listenAddr,
const string &nameArg,
Option option = kNoReusePort);
//设置从线程个数
void setThreadNum(int numThreads);
void start();
/// 当⼀个新连接建⽴成功的时候被调⽤
void setConnectionCallback(const ConnectionCallback &cb)
{
connectionCallback_ = cb;
}
/// 消息的业务处理回调函数---这是收到新连接消息的时候被调⽤的函数
void setMessageCallback(const MessageCallback &cb)
{
messageCallback_ = cb;
}
};
muduo::net::EventLoop:用于循环地监控事件,需要调用 loop 接口开始监控,注意这是一个阻塞式接口
class EventLoop : noncopyable
{
public:
/// 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();
TimerId runAt(Timestamp time, TimerCallback cb);
/// Runs callback after @c delay seconds.
/// Safe to call from other threads.
TimerId runAfter(double delay, TimerCallback cb);
/// Runs callback every @c interval seconds.
/// Safe to call from other threads.
TimerId runEvery(double interval, TimerCallback cb);
/// Cancels the timer.
/// Safe to call from other threads.
void cancel(TimerId timerId);
private:
std::atomic<bool> quit_;
std::unique_ptr<Poller> poller_;
mutable MutexLock mutex_;
std::vector<Functor> pendingFunctors_ GUARDED_BY(mutex_);
};
muduo::net::TcpConnection:代表一个连接,当连接事件触发时,会创建 TcpConnection 对象。我们在从 Reactor 线程的回调函数中通常会用到它的 send 方法
class TcpConnection : noncopyable,
public std::enable_shared_from_this<TcpConnection>
{
public:
/// Constructs a TcpConnection with a connected sockfd
///
/// User should not create this object.
TcpConnection(EventLoop *loop,
const string &name,
int sockfd,
const InetAddress &localAddr,
const InetAddress &peerAddr);
bool connected() const {
return state_ == kConnected; }
bool disconnected() const {
return state_ == kDisconnected; }
void send(string &&message); // C++11
void send(const void *message, int len);
void send(const StringPiece &message);
// void send(Buffer&& message); // C++11
void send(Buffer *message); // this one will swap data
void shutdown(); // NOT thread safe, no simultaneous calling
void setContext(const boost::any &context)
{
context_ = context;
}
const boost::any &getContext() const
{
return context_;
}
boost::any *getMutableContext()
{
return &context_;
}
void setConnectionCallback(const ConnectionCallback &cb)
{
connectionCallback_ = cb;
}
void setMessageCallback(const MessageCallback &cb)
{
messageCallback_ = cb;
}
private