liufeng2023
日拱一卒
展开
-
327-writev和readv函数
它们只需一次系统调用就可以实现在文件和进程的多个缓冲区之间传送数据,免除了多次系统调用或复制数据的开销。参数fildes是文件描述符iov是一个结构数组,它的每个元素指明存储器中的一个缓冲区。结构类型iovec有下述成员,分别给出缓冲区的起始地址和字节数:参数iovcnt指出数组iov的元素个数,元素个数至多不超过IOV_MAX。Linux中定义IOV_MAX的值为1024。下图说明了参数iovcnt、iov及其所指数组与这两个函数的关系:1、writev()有了这两个函数,当想要集中写原创 2022-06-06 14:31:01 · 215 阅读 · 0 评论 -
326-Linux高效的wakeupfd进程间通信
是提供的一种系统调用,它可以用来实现事件通知。包含一个由内核维护的64位无符号整型计数器,创建时会返回一个文件描述符,进程可以通过对这个文件描述符进行来读取/改变计数器的值,从而实现进程间通信。 可以是以下值的 运算结果,用以改变 的行为。在 Linux 2.6.26 版本之前,没有使用参数 flags,必须指定为 0。muduo库中设置为0。在EventLoop类中有这么两个变量:EventLoop类本身就维护了一个eventfd事件,这个事件是为了唤醒子线程的。为什么?mainReactor和s原创 2022-06-06 12:14:16 · 118 阅读 · 0 评论 -
325-重写C++muduo库(muduo网络库项目扩展)
定时器可以采用: 链表/队列 时间轮(libevent) nginx定时器(红黑树)muduo库还有DNS域名解析服务!还提供了简单的HTTP服务器 !处理的是HTTP协议!RPC: 远程过程调用!提供了很多示例代码:QPS是多少就是每秒支持多少的查询!在linux上,需要单独编译安装 直接创建线程组,发送的时间,压力测试的时间,但是只能测试http服务的性能。先安装JDK 再安装Jmeter;测试http服务 tcp服务 生成聚合报告(生成详细的报表,起了多少个线程来模拟客户端,总共压力测试多长原创 2022-06-06 09:36:25 · 284 阅读 · 0 评论 -
324-重写C++muduo库(梳理总结)
上面只是一个反应堆模型,我们的是多个反应堆模型—one loop per thread 模型;下面是一个多线程的Multiple Reactor模型:channel主要做的事情是:封装了,还有一组回调方法。对于上层来说,如果有一个fd的话,它就会把fd打包成Channel通道,然后下发到Poller上。看看Poller的头文件:Poller有一个成员变量Channels,是一个map表,键就是channel打包的sockfd,值就是包含fd对应的Channel;如果poller检测到哪个fd有事件发原创 2022-06-05 21:55:38 · 266 阅读 · 0 评论 -
321-重写C++muduo库(测试代码)
我们写一个回响服务器,客户端发什么,服务端就回什么!定义EchoServer对象,其内部就会定义TcpServer对象,也就会创建Acceptor对象,Acceptor中会创建一个non-blocking listenfd,然后再bind;接下来在start函数中,进入listen状态!创建loopthread,将listenfd打包成accpetChannel注册到mainLoop,mainloop主要就是接收新用户的连接!后面就是打包成新连接…在example文件夹中的Makefile文件:原创 2022-06-04 23:39:26 · 127 阅读 · 0 评论 -
320-重写C++muduo库(自动编译脚本)
为autobuild.sh赋予可执行权限:执行即可编译:可以看到已经将头文件全部拷贝过来了:在打开lib目录:可以看到so库!原创 2022-06-04 11:54:39 · 106 阅读 · 0 评论 -
318-重写C++muduo库(TcpConnection)
mainloop拿到连接成功的通信connfd,通过轮询算法拿到一个subloop,最终将connfd打包成TcpConnection,注册到subloop;(TcpServer::newConnection函数就是做这个事的)TcpConnection连接只是保存了客户端通信的所有的数据;(需要一个Socket)但是最终subloop中的事件分发器Poller主要监听的还是一个Channel,所以TcpConnection的部分数据 + Socket打包成一个Channel注册到Poller中,Polle原创 2022-06-03 15:55:37 · 152 阅读 · 0 评论 -
315-重写C++muduo库(TcpConnection:Buffer缓冲区)
TcpConnection:成员变量:1、Socket和Channel: TcpConnection成员变量包含Socket和Channel(Channel中的fd就是封装好的Socket)2、回调函数:TcpConnection里面有用户预设置好的回调函数(ConnectionCallback:连接成功执行的回调;MessageCallback:连接上有数据发生执行的回调;WriteCompleteCallback:服务端给客户端将数据send完之后的回调;HighWaterMarkCallback:高水原创 2022-06-02 11:29:26 · 172 阅读 · 0 评论 -
311-重写C++muduo库(TcpServer代码)
# TcpServer代码Acceptor是在mainloop中做事情了,做事情的回调函数是由TcpServer给它传递的!## TcpServer.h![在这里插入图片描述](https://img-blog.csdnimg.cn/c04ddd5452ec4a91a51e251cb168ecc8.png)![在这里插入图片描述](https://img-blog.csdnimg.cn/afc76698918b459e9cab47b1c6f7dabd.png)![在这里插入图片描述](https原创 2022-06-01 12:29:43 · 208 阅读 · 0 评论 -
308-重写C++muduo库(Acceptor)
AcceptorAcceptor就是accept函数的一个封装!Acceptor的底层也是一个listenfd(封装的acceptSocket_),这个listenfd也需要打包成Channel放在一个Poller上来监听有没有新用户的连接(即acceptChannel_),最终会返回发生的事件!当然还需要一个EventLoop,需要监听lisentd的Channel事件,就需要通过EventLoop!在后面的TcpServer中,TcpServer直接将用户定义的baseloop(也可称为ma原创 2022-05-31 11:35:35 · 127 阅读 · 0 评论 -
307-重写C++muduo库(Socket封装fd)
Socket封装fd这3部分代表Reactor模型的Reactor反应堆和Demultiplex事件分发器;经典的one loop per thread网络模型 :一个线程中创建了一个绑定线程的EventLoop,one loop per threadmuduo库是一个Multiple Reactors模型:可以通过setThreadNumber来设置底层的线程数量,一个IO线程(mainReactor)和 多个工作线程(subReactor)。***Acceptor:处理原创 2022-05-31 09:57:12 · 161 阅读 · 0 评论 -
303-重写C++muduo库(EventLoopThreadPool池)
EventLoopThreadPool池这个很明显,是池的概念。是一个事件线程池,管理EventLoop,EventLoop绑定的就是一个线程。1、EventLoopThreadPool.h在EventLoopThread类中,会创建EventLoop,会返回EventLoop的地址:注意: 线程初始化的回调函数是从上面传下来的。#pragma once#include "noncopyable.h"#include <functional>#include <st原创 2022-05-30 15:24:37 · 124 阅读 · 0 评论 -
302-重写C++muduo库(EventLoopThread事件线程类)
EventLoopThread事件线程类前面的Thread类,只是封装了一个线程;EventLoopThread:one loop per thread,一个线程中有一个loop,一个loop运行在一个线程上!1、EventLoopThread.hmuduo库中的信号量和互斥锁的相关操作,我们直接使用C++11里面的Thread类相关操作,不使用Linux系统的了,更加方便快捷!ThreadInitCallback线程初始化的一个回调操作,因为底层一个loop运行在一个线程,要做一些初始化的原创 2022-05-30 12:29:43 · 154 阅读 · 0 评论 -
301-重写C++muduo库(Thread线程类)
获取线程tid代码EventLoop包括底层的Poller(也就是事件分发器epoll)不会只工作在一个线程中;是one loop per thread,一个loop对应一个线程,一个线程对应一个线程;现在我们已经将EventLoop中的Channel,Poller,EpollPoller都实现完了;接下来剖析和EventLoop相关的Thread类,设计三个类:1、EventLoopThreadPool:事件循环的线程池,管理事件循环线程调度的;(这段代码是在TcpServer中的)2、原创 2022-05-30 11:25:35 · 142 阅读 · 0 评论 -
297-重写C++muduo库(EventLoop事件循环)
EventLoop事件循环EventLoop相当于Reactor模型的Reactor反应堆的角色;Poller和EPollPoller相当于Demultiplex多路事件分发器,就是epoll的所有操作;最起码得有一个线程来支撑。1、EventLoop.h成员变量:ChannelList: EventLoop中管理了很多Channel和一个Channel;looping_: 事件循环是正常运行还是退出循环(atomic,我们使用C++11CAS实现的)quit_: 客户端全部断开原创 2022-05-30 10:03:01 · 475 阅读 · 0 评论 -
296-重写C++muduo库(获取线程tid代码)
获取线程tid代码EventLoop就是对应的Reactor反应堆的组件!EPollPoller对应的是Demultiplex多路事件分发器的组件!Reactor调用Demultiplex相应的操作,对应muduo库上 就是EventLoop调用Poller、EPollPoller的相关操作;Channel通过调用EventLoop相应的方法在Poller事件分发器上添加、删除、修改事件!我们的服务器程序不一定就只有1个EventLoop,我们可能有很多的EventLoop,每个线程都有一个E原创 2022-05-29 10:02:45 · 176 阅读 · 0 评论 -
295-重写C++muduo库(EPollPoller事件分发器)
EPollPoller事件分发器newDefaultPoller函数给我们muduo库的上层,也就是给EventLoop返回一个具体的IO复用的实例!(默认生成的是epoll实例)1、EPollPoller.hoverride表示在派生类里面,这些方法是覆盖方法。必须由编译器来保证在基类里面一定有这些函数的接口的声明。在派生类要重写他们。给EPollPoller的析构函数写override,就是让编译器给你检查基类的析构一定是虚函数。底层是vector,放epoll_event,可以原创 2022-05-28 23:51:23 · 187 阅读 · 0 评论 -
294-重写C++muduo库(Poller抽象类)
Poller抽象类Poller中有好几个纯虚函数,是抽象类。为什么muduo库要抽象一层Poller?因为在EventLoop里面,在使用I/O复用的时候,并没有直接指定epoll;因为muduo库对外提供I/O复用的能力有2个:1个是poll(PollPoller),1个是epoll(EPollPoller类);在EventLoop里面,不可能直接去使用poll或者epoll。是从抽象层面直接使用抽象类Poller,到时候引用不同的派生类对象,调用同名覆盖方法,就可以非常方便地去扩展不同的原创 2022-05-27 15:11:16 · 118 阅读 · 0 评论 -
292-重写C++muduo库(Channel代码)
Channel通道代码TcpServer相当于是muduo库提供给外部编写服务器程序的入口的一个类,相当于一个大箱子,把muduo库有关服务器的编程相关的东西,包括反应堆,事件分发器,事件回调都打包一块了。我们看看它的成员变量:Acceptor:和accept相关的操作;EventLoopThreadPool:事件循环的线程池;ConnectionMap:和连接相关;eventloop就是Reactor模型中的事件循环,相当于事件分发器,相当于是一个epoll,epoll主要管理成员变量原创 2022-05-26 16:44:32 · 215 阅读 · 0 评论 -
291-重写C++muduo库(InetAddress.h & InetAddress.cc代码)
InetAddressTCPServer就是我们用muduo库编程 服务器程序的入口的类,我们经常自定义一个类,把TCPServer对象组合一下。eventloop就是事件循环,相当于多路事件分发器,相当于epoll,InetAddress,需要这个对象来打包IP地址和端口号作为TCPServer对象的构造函数的参数。1、InetAddress.h注意: 我们的InetAddress没有实现ipv6,只实现了ipv4!#pragma once#include <arpa/ine原创 2022-05-26 11:18:26 · 115 阅读 · 0 评论 -
290-重写C++muduo库(Timestamp.h & Timestamp.cc代码)
Timestamp.h & Timestamp.cc代码Timestamp.h#pragma once#include <arpa/inet.h>#include <netinet/in.h>#include <string>//封装socket地址类型class InetAddress{public: explicit InetAddress(uint16_t port = 0, std::string ip = "127.0.0.原创 2022-05-26 09:35:39 · 122 阅读 · 0 评论 -
287-重写C++muduo库(日志代码:Logger.h & Logger.cc)
日志代码1、Logger.h使用格式化字符的方式!在写宏的代码时,分多行的话,每行的末尾都要加\,且\的后面不能加空格。我们系统的变量很多都写_开头,我们书写定义成员变量把_放在末尾,去和系统的变量不产生冲突,而且为了区分函数内的变量(局部变量)。我们创建Logger.h#pragma once#include <string>#include "noncopyable.h"//LOG_INFO("%s %d", arg1, arg2)//__VA_ARGS__获取原创 2022-05-25 11:55:44 · 194 阅读 · 0 评论 -
286-重写C++muduo库(noncopyable.h代码)
noncopyable1、muduo库中的noncopyable.h不写继承方式,class是默认private,struct默认是publicnoncopyable不可复制的意思,我们来看看:把拷贝构造函数和赋值函数都delete掉了;使用默认的构造函数和析构函数,保护权限;(基类的构造和析构是保护的,派生类是可以访问的,外部无法访问!)TCPServer的对象可以创建,调用基类的构造函数,基类的构造和析构是保护的,派生类是可以访问的,外部无法访问!基类的拷贝构造函数和赋值函数直接原创 2022-05-25 10:48:29 · 282 阅读 · 0 评论 -
285-重写C++muduo库(构建项目编译CMake文件)
构建项目编译CMake文件使用vscode+ubuntu18.04构成远程编译环境!我们创建的项目工程名:mymuduo21、CMakeLists.txt我们在mymuduo下创建CMakeLists.txtcmake_minimum_required(VERSION 2.5)project(mymuduo)# cmake => makefile make# mymuduo最终编译成so动态库,设置动态库的路径,放在根目录的lib文件夹下面set(LIBRARY_OUTPU原创 2022-05-25 10:21:47 · 186 阅读 · 0 评论 -
182-muduo网络库(陈硕)编程
1、muduo网络库编程muduo网络库的底层就是epoll加linux的pthread线程库。所以muduo库只能装在linux环境中。muduo网络库的安装:https://blog.csdn.net/QIANGWEIYUAN/article/details/89023980我们在做项目的时候,服务器一定要做到高并发,要用到muduo库。但是客户端只是向服务器请求服务,不需要高并发的性能要求。2、基于muduo的客户端服务器编程muduo网络库的编程很容易,要实现基于muduo网络库的服原创 2022-05-10 00:51:04 · 1247 阅读 · 0 评论 -
284-select、poll、epoll对比总结
select,poll,epoll对比总结select和poll的缺点select的缺点:1、单个进程能够监视的文件描述符的数量存在最大限制,通常是1024,当然可以更改数量,但由于select采用轮询的方式扫描文件描述符,文件描述符数量越多,性能越差;(在linux内核头文件中,有这样的定义:#define __FD_SETSIZE 10242、内核 / 用户空间内存拷贝问题,select需要复制大量的句柄数据结构(文件描述符),产生巨大的开销3、select返回的是含有整个句柄的数组,应用程原创 2022-05-25 09:18:24 · 133 阅读 · 0 评论 -
279-Reactor模型
Reactor模型The reactor design pattern is an event handling pattern for handling service requestsdelivered concurrently to a service handler by one or more inputs. The service handlerthen demultiplexes the incoming requests and dispatches them synchronous原创 2022-05-24 12:07:08 · 167 阅读 · 1 评论 -
278-设计良好的网络服务器
设计良好的网络服务器1、在这个多核时代,服务端网络编程如何选择线程模型呢?赞同libev作者的观点: one loop per thread is usually a good model,这样多线程服务端编程的问题就转换为如何设计一个高效且易于使用的event loop(事件循环),然后每个线程run一个event loop就行了(当然线程间的同步、互斥少不了,还有其它的耗时事件需要起另外的线程来做)。event loop 是 non-blocking (非阻塞)网络编程的核心,在现实生活中,non原创 2022-05-24 11:20:29 · 138 阅读 · 0 评论 -
277-Unix/Linux上的五种I/O模型
Unix/Linux上的五种I/O模型I/O模式是操作系统上任何的I/O,内存I/O,磁盘I/O,网络I/O都可以应用。我们主要考虑网络I/O。1、同步阻塞 blocking同步的阻塞的I/O模型,效率不高。内核空间就是网络接收到远端发送过来数据的tcp接收缓冲区。应用进程调用read,系统调用,是系统的I/O接口。在应用进程看来,是一直阻塞住,数据是否就绪、数据就绪后的从内核空间向用户空间的拷贝整个过程,应用程序时间都要在read上花费完,一直阻塞住。应用程序调用read这个I/O接口,原创 2022-05-24 10:54:47 · 85 阅读 · 0 评论 -
275-I/O阻塞和非阻塞,同步和异步
阻塞、非阻塞、同步、异步典型的一次I/O的两个阶段是什么?数据准备 和 数据读写我们作为服务器,接收客户端的请求,得先监听客户端有没有数据过来,这是一个状态,还有就是数据过来了该怎么去读写,这又是一个状态。实际上,阻塞,非阻塞,同步,异步, 分别是这两种状态下的体系。1、网络I/O阶段1:数据准备数据准备: 根据系统IO操作的就绪状态阻塞 : 让调用I/O的线程进入阻塞状态 ,数据准备好了就唤醒非阻塞: 不会改变线程的状态,通过返回值判断1.1、阻塞sockfd相当于就是系统的文件描原创 2022-05-23 21:29:46 · 169 阅读 · 1 评论 -
273-项目介绍:重写C++muduo库
项目介绍:基于muduo网络库实现的集群聊天服务器目的1、理解阻塞、非阻塞、同步、异步2、理解Unix/Linux上的五种IO模型3、epoll的原理以及优势4、深刻理解Reactor模型5、从开源C++网络库,学习优秀的代码设计6、掌握基于事件驱动和事件回调的epoll+线程池面向对象编程7、通过深入理解muduo源码,加深对于相关项目的深刻理解8、改造muduo,不依赖boost,用C++11重构知识储备1、TCP协议和UDP协议2、TCP编程和UDP编程步骤3、IO复用接口编原创 2022-05-23 09:47:13 · 517 阅读 · 0 评论