
从零开始搭建muduo网络库
文章平均质量分 76
从零开始搭建muduo网络库
TABE_
这个作者很懒,什么都没留下…
展开
-
Reactor和Proactor
另外,「单 Reactor」的模式还有个问题,因为一个 Reactor 对象承担所有事件的监听和响应,而且只在主线程中运行,在面对瞬间高并发的场景时,容易成为性能的瓶颈的地方。单 Reactor 单进程的方案因为全部工作都在同一个进程内完成,所以实现起来比较简单,不需要考虑进程间通信,也不用担心多进程竞争。所以,单 Reactor 单进程的方案不适用计算机密集型的场景,只适用于业务处理非常快速的场景。...原创 2022-08-16 11:16:34 · 480 阅读 · 0 评论 -
muduo库中各个类的简明介绍
muduobaseTimestamp时间戳类AtomicIntegerT模板类Types模板类Exception异常类Thread线程类MutexLock和MutexLockGuard互斥量类Condition条件变量类CountDownLatch计数类BlockingQueue无界缓冲区模板类BoundedBlockingQueue有界缓冲区模板类ThreadPool线程池类Singleton单例模板类ThreadLocal线程本地存储模板类ThreadLocalSingleton线程本地单例模板类日志相原创 2021-06-02 22:38:48 · 1189 阅读 · 0 评论 -
muduo笔记
muduo笔记一. muduo中各个类的作用二级目录三级目录一. muduo中各个类的作用1.mutex.h包含MutexLock和MutexLockGuard两个类,采用RAII技法封装了一个mutex_。2.Socket.h/Socket.cc(Socket类),用RAII方法封装套接字文件描述符。二级目录三级目录...原创 2021-05-29 21:53:16 · 123 阅读 · 0 评论 -
TcpServer类的启动过程
编写一段代码测试TcpServer类的功能#include <muduo/net/TcpServer.h>#include <muduo/net/EventLoop.h>#include <muduo/net/InetAddress.h>#include <stdio.h>using namespace muduo;using namespace muduo::net;void onConnection(const TcpConnectio原创 2021-04-15 22:32:44 · 759 阅读 · 0 评论 -
Acceptor类的函数调用过程
编写一小段代码测试Acceptor类的功能#include <muduo/net/Acceptor.h>#include <muduo/net/EventLoop.h>#include <muduo/net/InetAddress.h>#include <muduo/net/SocketsOps.h>#include <stdio.h>using namespace muduo;using namespace muduo::net原创 2021-04-08 00:35:07 · 280 阅读 · 0 评论 -
muduo库整体架构
下面这张图是陈硕提供的muduo 网络库的类图,本次讲解主要是围绕下面这张图,弄明白这样就相当于弄明白这个架构了。(图中灰色的类是内部类,白色的是外部类)。首先是EvenLoop类,他是事件循环(反应器 Reactor),每个线程只能有一个 EventLoop 实体,它负责 IO 和定时器事件的分派。 它用 TimerQueue 作为计时器管理,用 Poller 作为 IO Multiplexing。TimeQueue底层使用timerfd_*系列函数将定时器转换为fd添加到事件循环中,当时间到达后就会原创 2021-03-31 23:17:33 · 378 阅读 · 0 评论 -
net13. 主动发起连接类——Connector类
Connector类Connector负责主动发起连接,不负责创建socket,只负责连接的建立,外部调用Connector::start就可以发起连接,Connector具有重连的功能和停止连接的功能,连接成功建立后返回到TcpClient。数据成员:enum States:枚举类型,包含连接的状态static const int kMaxRetryDelayMs = 301000:30秒,最大重连延迟时间static const int kInitRetryDelayMs = 500:0.5秒原创 2021-03-30 21:48:29 · 361 阅读 · 0 评论 -
net12. 客户类——TcpClient
TcpClient类muduo用TcpClient发起连接,TcpClient有一个Connector连接器,TCPClient使用Conneccor发起连接, 连接建立成功后, 用socket创建TcpConnection来管理连接, 每个TcpClientclass只管理一个TcpConnecction,连接建立成功后设置相应的回调函数。很显然,TcpClient用来管理客户端连接,真正连接交给Connector。TcpClient具备TcpConnection断开之后重新连接的功能,加上Conn原创 2021-03-30 21:29:17 · 493 阅读 · 0 评论 -
net11. 应用层缓冲区类——Buffer
Buffer类为什么采用non-blocking网络编程中应用层buffer是必需的?non-blockingIO的核心思想是避免阻塞在read()或write()或其他IO系统调用上,这样可以最大限度地复用thread-of-control。让一个线程能服务于多个socket连接。IO线程只能阻塞在IOmultiplexing函数上,如select/poll/epoll_wait。这样一来,应用层的缓冲是必需的,每个TCPsocket都要有stateful的input buffer和output b原创 2021-03-29 22:20:16 · 438 阅读 · 0 评论 -
net10. IO线程池类——EventLoopThreadPool
EventLoopThreadPool类EventLoopThreadPool是事件循环线程池,管理所有客户端连接,每个线程都有唯一一个事件循环。可以调用setThreadNum设置线程的数目。EventLoopThreadPool类又叫IO线程池类,由1个主线程+N个子线程组成,“1+N”的模式一般用在服务端,主线程用于接收所有客户端的连接请求,各子线程用于处理多个客户端的IO事件。给线程池分配客户端的时候采取循环分配的方式,保证线程池的负载平衡。多个客户端的IO操作可以对应于1个IO线程,但是1个原创 2021-03-29 21:52:10 · 341 阅读 · 0 评论 -
net9. Tcp连接类——TcpConnection
TcpConnection类TcpConnection用来表示一个 TCP 连接, 不可再生, 如果这个连接断开, 那么该TcpConnection就失去了意义TcpConnection中包含有封装好的读写 buffer, 用来收发数据TcpConnection的生命周期由智能指针shared_ptr来管理, 具体在下面的注释中有TcpConnection对象有四个状态, 表示连接的正在建立, 建立完成, 处于断开 (TcpConnection不主动关闭一个连接,都是等客户端主动关闭), 已经断开原创 2021-03-29 21:29:42 · 969 阅读 · 0 评论 -
net8. 服务器类——TcpServer
TcpServer类TcpServer由用户直接使用,生命周期由用户控制,用户设置好相应的回调MessageCallback、ConnectionCallback传递给TcpServer即可;MessageCallback为连接上有接收数据时调用的回调(处理业务逻辑),这些数据存放在连接的应用层接收缓冲区中;ConnectionCallback在连接建立和断开时都会回调,主要是通知用户进行相应的处理。在TcpServer中,建立连接描述符和TcpConnection之间的关系,通过stl中map来实现原创 2021-03-29 21:15:22 · 1635 阅读 · 0 评论 -
net7. 被动接受连接类——Acceptor
Acceptor用于接收client的连接请求,建立连接Acceptor的主要功能包括socket、bind、listen,并调用注册的回调函数来处理新到的连接。Acceptor用于accept(2)接受TCP连接。Acceptor的数据成员包括Socket、Channel,Acceptor的socket是listeningsocket(即serversocket)。Channel用于观察此socket的readable事件,并回调Accptor::handleRead(),后者调用accept.原创 2021-03-29 21:02:49 · 222 阅读 · 0 评论 -
net6. 套接字封装类——Endian、SocketsOps、Socket、InetAddress
Endian.h封装了字节序转换函数(全局函数,位于muduo::net::sockets名称空间中)。SocketsOps.h/ SocketsOps.cc封装了socket相关系统调用(全局函数,位于muduo::net::sockets名称空间中)。Socket.h/Socket.cc(Socket类)用RAII方法封装socket file descriptor。InetAddress.h/InetAddress.cc(InetAddress类)网际地址sockaddr_in封装。1原创 2021-03-29 20:37:51 · 794 阅读 · 0 评论 -
net5. IO线程类——EventLoopThread
EventLoopThread类图这个类体现了muduo库的思想:每一个线程有且有一个eventloop对象。此类的功能也是,创建一个线程,并在线程的回调函数中创造一个eventloop对象数据成员:EventLoop* loop_:loop_指针指向一个EventLoop对象bool exiting_:线程是否退出Thread thread_:线程对象thread_MutexLock mutex_:互斥量对象mutex_Condition cond_:已经创建的线程的个数,原子整数类Th原创 2021-03-29 19:51:33 · 353 阅读 · 0 评论 -
net4. 定时器类——TimerId、Timer、TimerQueue
定时器类图TimerId:用户只能看到这个类,是一个不透明的类,cancel()函数用这个类来取消定时器Timer:对定时操作进行抽象的定时器类TimerQueue:定时器队列时序图:1.TimerId类数据成员:Timer* timer_:定时器timer_int64_t sequence_:定时器的序号,每个定时器都有唯一的一个编号成员函数:TimerId():构造函数TimerId(Timer* timer, int64_t seq):构造函数TimerId.h#ifnd原创 2021-03-28 21:52:12 · 1106 阅读 · 0 评论 -
net3. Reactor关键结构——Poller轮询器类
Poller是一个抽象类,Poller是对I/O复用的抽象,有两个派生类PollPoller和EPollPoller,一个EventLoop包含一个Poller对象Poller类数据成员:EventLoop* ownerLoop_:Poller所属EventLooptypedeftypedef std::vector<Channel*> ChannelList成员函数:Poller(EventLoop* loop):构造函数,记录Poller所属EventLoopvirtual原创 2021-03-23 23:32:19 · 363 阅读 · 0 评论 -
net2. Reactor关键结构——Channel通道类
时序图:数据成员:static const int kNoneEvent:常量,表示没有事件static const int kReadEvent:常量,表示读事件static const int kWriteEvent:常量,表示写事件EventLoop* loop_:Channel所属的EventLoopconst int fd_:文件描述符,但不负责关闭该文件描述符 int events_:关注的事件int revents_:poll/epoll返回的事件int index_:如原创 2021-03-23 23:02:54 · 526 阅读 · 0 评论 -
net1. Reactor关键结构——EventLoop事件循环类
muduo的简化类图时序图:EventLoop事件循环类,是对事件循环的抽象one loop per thread意思是说每个线程最多只能有一个EventLoop对象。EventLoop对象构造的时候,会检查当前线程是否已经创建了其他EventLoop对象,如果已创建,终止程序(LOG_FATAL)EventLoop构造函数会记住本对象所属线程(threadId_)。创建了EventLoop对象的线程称为IO线程,其功能是运行事件循环(EventLoop::loop)一个EventLoop原创 2021-03-23 22:03:37 · 627 阅读 · 1 评论 -
base13. LogFile日志滚动类、FileUtil小文件日志类
LogFile类图日志滚动类LogFile,是线程安全的,支持多个线程对同一个文件写入,但效率可能不比单个线程高,因为I/O不一定可以并行。若要提高多线程写入到同一个日志文件的效率,可以采用异步日志LogFile类嵌套了一个File类,File类不是线程安全的,写入是通过不加锁的方式进行的数据成员:const string basename_:日志文件的basenameconst size_t rollSize_:日志文件达到rolSize_就换一个新文件const int flushInte原创 2021-03-23 00:05:28 · 267 阅读 · 0 评论 -
base12. LogStream日志输出流类
FixedBuffer模板类图数据成员:char data_[SIZE]:data_为缓冲区,SIZE为容量char* cur_:cur_指针,指向缓冲区中第一个可用的地址void (*cookie_)():该函数指针目前还没什么作用成员函数:FixedBuffer():构造函数,调用setCookie()函数~FixedBuffer():析构函数,调用setCookie()函数void append(const char* buf, size_t len):在buf(不是data_)中原创 2021-03-22 23:23:37 · 298 阅读 · 0 评论 -
base11. Logger日志类和Impl日志实现类
muduo库通过这几个宏的日志输出,既可以输出到标准输出,又可以输出到宏__FILE__是这一行代码所在的文件名,__LINE__是这一行代码所在的行号#define LOG_TRACE if (muduo::Logger::logLevel() <= muduo::Logger::TRACE) \ //构造匿名对象,在调用完Logger.stream()之后,会自动调用析构用函数 // // 匿名对象只存在于该行代码,离开这行代码后立即调用析构函数 muduo::Logger(__F原创 2021-03-22 22:57:54 · 500 阅读 · 0 评论 -
base10. ThreadLocalSingleton线程本地单例模板类
ThreadLocalSingleton类图数据成员:static _thread T* t_value:一个类型是T的线程本地指针t_value,该指针是POD类型,故线程本地存储可以用__thread关键字static Deleter deleter:一个类型是Deleter的deleter_对象,deleter_对象主要是为了能够调用destructor使得t_value_可以被自动释放成员函数:static T& instance():返回单例对象t_value_的引用,调用de原创 2021-03-22 21:43:47 · 181 阅读 · 0 评论 -
base9. ThreadLocal线程本地存储模板类
ThreadLocal类图数据成员:pthread_key_t pkey_:一个指向线程特定数据的pthread_key_t类型的pkey_对象成员函数:ThreadLocal():构造函数,调用pthread_key_create()创建pkey_,并注册销毁函数destructor()~ThreadLocal():析构函数,调用pthread_key_delete()销毁pkey_T& value():获取线程的特定数据pkey_static void destructor(vo原创 2021-03-22 21:30:13 · 153 阅读 · 0 评论 -
base8. Singleton单例模板类——线程安全的
Singleton类图数据成员:static pthread_once_t ponce_:一个pthread_once_t类型的ponce_对象,ponce_保证一个函数只被执行一次static T* value_:一个类型为T的指针成员函数:static T& instance():返回单例对象*value_Singleton():构造函数~Singleton():析构函数static void init():创建T类型对象value_,并注册销毁函数destroy()stat原创 2021-03-22 21:20:56 · 187 阅读 · 0 评论 -
base7. ThreadPool线程池类——生产者与消费者模型
ThreadPool类图数据成员:MutexLock mutex_:一个MutexLock类型的互斥变量mutex_Condition cond_:一个Condition类型的条件变量cond_string name_:线程池的名称boost::ptr_vector<muduo::Thread>threads_:消费者线程队列threads_std::deque<task. >queue_:任务队列queue_,其中task为一个执行任务的函数,生产者线程在queue_原创 2021-03-22 21:08:20 · 332 阅读 · 0 评论 -
base6. BlockingQueue无界缓冲区模板类、BoundedBlockingQueue有界缓冲区模板类——生产者与消费者模型
BlockingQueue类图数据成员:mutable MutexLock mutex_:一个MutexLock类型的锁mutex_Condition notEmpty_:一个Condition类型的信号量notEmpty_,用于通知队列非空std::deque queue_:一个类型T的队列成员函数:BlockingQueue():构造函数初始化数据成员void put(const T& x):生产者生产产品,并通知消费者队列已有产品T take():消费者消费产品size_t原创 2021-03-22 20:55:23 · 393 阅读 · 0 评论 -
base5. MutexLock和MutexLockGuard互斥量类、Condition条件变量类、CountDownLatch倒计时门栓类(计数类)
MutexLock类图数据成员:pthread_mutex_t mutex_:pthread_mutex_t类型的线程互斥量mutex_pid_t holder_:holder_用于保存锁拥有者的线程tid成员函数:MutexLock():构造函数,初始化mutex_~MutexLock():析构函数,销毁mutex_bool isLockedByThisThread():判断当前线程是否拥有该锁void assertLocked():断言当前线程拥有该锁void lock():加锁,并原创 2021-03-22 20:28:33 · 458 阅读 · 0 评论 -
base4. Thread线程类
Thread类图原创 2021-03-22 19:46:03 · 191 阅读 · 0 评论 -
base3. Exception异常类
Exception类图数据成员:string message_:异常信息字符串string stack_:异常发生时的调用函数的栈信息成员函数:explicit Exception(const char* what):构造函数,用what初始化message_explicit Exception(const string& what):构造函数,用what初始化message_virtual ~Exception() throw():析构函数virtual const char*原创 2021-03-19 00:04:11 · 303 阅读 · 0 评论 -
base2. Atomic原子操作,Types类型转换
AtomicIntegerT模板类图数据成员:volatile T value_:T类型的值原创 2021-03-18 23:45:59 · 321 阅读 · 0 评论 -
base1. Timestamp时间戳类
Timestamp类图数据成员:static const int kMicroSecondsPerSecond:微秒与秒之间的进制关系int64_t microSecondsSinceEpoch_:从1970年1月1日起至当前的微秒数成员函数:Timestamp():构造一个microSecondsSinceEpoch_==0的失效时间戳Timestamp(int64_t microSecondsSinceEpoch):构造一个microSecondsSinceEpoch_==microSec原创 2021-03-18 22:21:01 · 511 阅读 · 0 评论