自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(48)
  • 收藏
  • 关注

原创 课后笔记--程序的编译链接原理梳理

1.gcc test.c 经历了什么?// test.cc#include <stdio.h>int main(){ printf("gcc compilation link process."); return 0;}  有 预编译、编译、汇编、链接 四个步骤,下面逐一分析:预编译  也叫预处理阶段,主要操作有这几个:展开所以 #define 宏定义 ,进行文本替换删除所有的注释处理条件编译 #ifdef #endif

2021-06-21 21:31:30 137 1

原创 SGI STL二级空间配置器内存池源码剖析理解

背景空间配置器做什么事情?分离了对象的内存开辟和对象构造分离了对象的析构和内存空间的释放为什么要将内存开辟释放与对象的构造析构分离?    拿vector来举例,当pop_back()元素的时候,我们只想让最后面的这个元素析构,但是这个空间我还是需要的,如果底层直接调用了delete,那么这块空间就没了,不能说pop_back()后,vector的capacity也跟着减少。这样肯定是不行的。因此需要将对象的析构和内存空间的释放分开。为什么要引

2021-06-20 22:12:06 192 2

原创 分布式服务配置中心——Zookeeper初窥

  在自己写rpc的时候,最开始提供服务的主机ip和端口都是在配置文件中写死的,也就是说服务的请求方通过读取配置文件能知道服务提供方的ip和端口,但是,在实际的远程方法调用框架中,不可能实现把所有的服务提供方的ip和端口号事先提供,因为每个客户端都保存的是一个静态的列表,一旦服务的提供者发生变化,比如某些机器down了,或者又新增了一些服务,客户端这边是根本不知道的。那么需要一个服务配置中心,我的服务请求方只需要知道服务配置中心的ip和port,然后在服务配置中心里通过我请求的方法来给我

2021-06-04 21:43:25 195 3

原创 读muduo源码之——代码设计上的启发

在阅读muduo远码时,发现有很多类都是继承于noncopycale:初看时不解其意,猛然间看懂觉得实在巧妙,我们先来看看noncopycale类到底是啥样的:namespace muduo{class noncopyable{ public: noncopyable(const noncopyable&) = delete; void operator=(const noncopyable&) = delete; protected: noncopy

2021-05-27 16:28:06 250

原创 RPC 框架梳理——RPC使用方的调用流程梳理

背景 myrpc是基于protobuf开发的远程调用框架,对于rpc服务,在proto文件中的定义如下:   经过protoc编译后,会生成两个类:UserServiceRpc 和 UserServiceRpc_Stub,在之前的文章中已经分析过,UserServiceRpc_Stub类是继承于UserServiceRpc,两者均继承于protobuf中是service这个基类,其中UserServiceRpc_Stub是供rpc访问的消费者(调用方)使用。

2021-05-22 15:47:24 485

原创 日志系统的设计的一些思考

背景   最近在写一个rpc框架,功能加多后,一些打印信息都在控制台上,显得很凌乱出现问题的时候也比较难找难以定位问题所在,于是考虑学习加入一个日志功能:可能出现的问题及解决思路1.写日志这个操作是磁盘I/O,本身速度慢,如果写日志这个操作直接是写入磁盘,那么这个时间花销就算在了业务执行过程中,会导致rpc的业务处理效率降低。   解决思路:中间加入一个队列,将写日志操作变成异步的2.有多个工作线程会写日志到队列中,另外会有一个专门的写日志线程将队列中的消

2021-05-21 14:08:45 186

原创 RPC 框架梳理——rpc框架对远程调用的处理流程梳理

背景  当rpc服务的发布方启动了rpc服务的发布节点后,rpc服务的提供方便进入阻塞状态,等待远程的rpc调用请求。  首先我们要梳理,在run中,rpc框架主要做了哪些事情。因为myrpc框架是基于木朵网络库开发的,所以网络部分使用了muduo的epoll+多线程。Run()主要工作就是提供rpc网络监听。  主要设置有新连接时的回调处理、设置有新消息(有rpc请求)时的回调处理。本文主要梳理当有rpc请求时的框架处理流程。有rpc

2021-05-20 08:34:02 378

原创 RPC 框架梳理——rpc服务在rpc框架上的注册流程梳理

背景 本地服务想要发布到rpc框架上,要首先本地定义proto文件,将要发布在rpc框架上的方法写入相应的service中。service UserServiceRpc{ rpc login(LoginRequest) returns(LoginResponse); rpc Register(RegisterRequest) returns(RegisterResponse);}   这里面定义了一个UserServiceRpc,里面包含两个方法lo

2021-05-19 19:42:34 656 2

原创 protobuf中RpcChannel的CallMethod方法的RpcController参数的探究

背景   我们知道在protobuf中定义了service UserServiceRpc后,经过protoc编译后,会生成两个类class UserServiceRpc 和 class UserServiceRpc_stub,UserServiceRpc 是继承于service基类,UserServiceRpc_stub是继承于UserServiceRpc 。UserServiceRpc是供给rpc服务发布者(生产者)使用,UserServiceRpc_stub是供给rpc服务的调用方

2021-05-18 16:08:16 646 1

原创 如何设计解析rpc请求,避免出现粘包问题

背景  对于远程调用的请求方,它的请求包含以下内容:服务的名称(请求的方法所在的类名称)、请求的方法名称、该请求方法的参数。由于请求方发来的数据是字符流,那么就涉及到接收方如何读取才能正确的解析各个部分数据。字符流的构成header_size(4个字节)+(service_name/method_name/args_size ) +args1.header_size: 数据头的长度即(service_name/method_name/args_size )的长度2.servic

2021-05-17 22:52:47 358

原创 redis消息队列实现跨服务器通信的梳理

定义用于操作redis消息队列的类——Redissubscribe:向redis指定的通道subscribe订阅消息,如服务器1中的client1登录上线了,其用户id为1,那么subscribe(1),即告诉消息队列,如果有channel为1 的消息,告诉我。流程梳理1.每个服务器启动后,其事务处理类ChatService的构造函数中,先注册一个回调函数,用来处理当其消息队列中有该服务器订阅频道的信息后的一系列操作(将该频道的信息发送给注册该回调的服务器上的用户)。2.当用户在该服务器登录上线后

2021-05-15 13:33:33 462

原创 ubuntu下编译安装protobuf

1.在github上克隆protobuf源码:  git clone https://github.com/google/protobuf2.解压压缩包:  unzip protobuf-master.zip3.安装所需要的工具:4.自动生成configure配置文件  5.配置环境:6.编译源代码:make7.安装:8.刷新动态库:...

2021-05-14 15:22:06 340

原创 跨服务器通信问题的思路——基于发布订阅的消息队列

问题背景  在我的聊天服务器项目中,尝试使用nginx的tcp负载均衡来提升多并发的能力,与此同时也带来了另一个问题。因为有了多台服务器,就必须要解决跨服务器通信的问题。  在服务器中有一个_userConnMap,用于存储当前在线用户及其TcpConnection问题解决思路&&步骤  假设当前处理client1业务的服务器是Chatserver1,处理client2业务的服务器ChatServer2。client2和client2是好友关

2021-05-14 08:49:46 381

原创 nginx的tcp负载均衡的配置

应用背景  在做聊天服务器的时候,因为是自己练手的小项目,所以数据量和并发量都很小,但是一般来说,聊天服务器要支持的连接数据肯定远远高于我练习的数量级。这个时候,我这个最多两万左右的连接数据就很不够看。从更好的学习和锻炼的角度出发,我浏览了相关的资料,考虑部署多台服务器。  这个时候就面临了一个新问题,当部署多个服务器共同处理客户端的并发请求时,客户端怎么知道去具体连接哪台服务器呢?查阅相关博文,要处理此类问题,需要一台负载均衡器,通过预设的负载均衡算法,指导客户端连接服务器。此处先

2021-05-13 15:36:43 409

原创 聊天服务器踩坑——服务器异常关闭

问题描述  在进行服务器功能测试的时候,直接ctrl+c关掉的服务器,当前在线用户在数据库中的状态仍为“online”,与客观逻辑不符合,服务器都死掉了用户还是在线状态。且导致后续用户无法正常登录。问题解决的思路 这个问题是由ctrl+c导致服务程序异常关闭,那么考虑能否截获信号,再截获信号后对用户的状态信息进行重置。这样应该能够避免上述问题的发送。 于是在网上搜索如何截获 ctrl+c:链接: 关于捕获信号. 需要引入头文件#include<signal.h>,在信号的处理函数

2021-05-10 22:35:33 241

原创 聊天服务器踩坑——用户异常退出

问题描述  在做聊天服务器用户登录测试时,在登录成功后,在终端输入了 ctrl+z 结束了会话,导致客户端异常推出,之后该用户便一直无法正常登录。问题原因  在用户登录方法中,考虑到了用户重复登录的问题,所以在用户登录的时候会先判断用户的状态 state是‘online’还是‘offline’ ,如果是online就说明用户已经登录在线了,就不允许再次登录,如下: if(user.getState()=="online") { //该用户以及登录,不允许重复

2021-05-10 14:26:23 150

原创 远程连接Linux mysql出错

关于linux mysql远程访问失败的坑问题描述思考有哪些原因导致的1.SQL服务器是否正常启动了2.是不是登录用户、密码、数据库名称错误3.是否是权限问题依次验证排查1.先检查mysql是否正常工作2.检查用户、密码以及数据库的名称是否正确问题描述 在搭建聊天服务器的时候,我是在vscode中远程连接我的ubuntu电脑。在ubuntu电脑上,事先配置了MySQL的环境,安装了mysql的开发包。因为ubuntu默认安装最新的mysql,但是初始的用户名和密码是自动生成的,所以自己修改了mysql的

2021-05-09 23:07:27 173

原创 volatile关键字

和const一样,volatile也是一种类型修饰符。下面是对比案例: int i =10; int j = i; //语句一 int k = i; //语句二 此时编译器对代码进行优化,因为在一、二两条语句中,i没有被赋值。这时候编译器就认为i的值没有发生变化,所以在语句一时从内存中取出i的值赋给j后,这个值并没有被丢掉,而是在语句二中继续用这个值给k赋值。即编译器不会生成出汇编代码重新从内存中取i的值。 volatile int i= 10; int j...

2020-06-16 13:50:20 107

原创 include的两种形式& CPP的搜索路径

#include"stdio.h" // 1.源文件所在路径 2.-I选项 所指定的路径 3.环境变量包含的路径 (C_INCLUDE_PATH) 4.预配置的路径(cpp -v)#include<stdio.h> //1.-I选项所指定的路径 2.环境变量包含的路径 3.预配置的路径以上两种方法的区别在于预处理器对于头文件的搜索(CPP也就是我们的预处理器)。需要注意的是,在不同的平台上预配置的路径是不同的,并且即使在同一平台下,把gcc装...

2020-06-13 16:46:39 629

原创 在Anaconda3下,切换环境,把python脚本打包成exe文件

背景介绍  本机用Anaconda安装有 python2和python3 的环境在命令行切换自己要使用的python版本  activaye py27安装pyinstaller输入pyinstaller,查看是否安装成功:测试能否打包成功  打开我们需要打包的python程序的路径:   输入命令如下:pyinstaller -F tfpic.py  之后便可以在该...

2019-10-25 17:42:02 2611 1

原创 C++ 编码规范总结

  具有良好编码规范的代码就是在保证高质量完成需求的同时具备良好的可读性、可维护性。注释的编写规范文件头的注释  该部分主要涉及到作者名、文件名称、文件名称、生成日期等函数的注释  1.对于关键函数,必须写上注释,说明函数的用途。  2.对于函数中的特别参数,需要说明参数的目的,由谁负责释放等…  3.一般函数的注释要写在代码之前。  4.尚未完善的代码或需要进一步完善的代码,应加...

2019-10-14 10:18:49 137

原创 linux下利用statfs函数查看磁盘使用情况

  最近在学习Linux的过程中,需要查看磁盘使用情况,于是查找资料,发现statfs函数可以胜任这个任务.下面将简单介绍statfs函数及其使用。  函数如下:  int statfs(const charpath, struct statfsbuf); 参数:  path: 位于需要查询信息的文件系统的文件路径  buf: statfs结构体类型的指针变量,用于存储文件系统的相关...

2019-09-06 15:42:52 1222

原创 Makefile学习笔记(二)

Makefile的规则  target是一个目标文件,可以是Object File,也可以是执行文件,或者是个标签。这是一个文件的依赖关系,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中,如果prerequisites中有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。示例  我们把这个内容保存在“...

2019-09-06 09:53:54 78

原创 Makefile学习笔记(一)

概述  在一个工程中有很多源文件,按照其类型、功能、模块分别放在若干目录中,makefile定义了一系列的规则来指定那些文件需要先编译,那些需要后编译,还有一些更复杂的功能操作(在windows中,IDE已经为我们做了这些工作)。makefile的特点就是“自动化编译”,一旦写好一个make命令,整个工程完全自动编译。程序的编译和链接  一般来说,无论是C、C++还是其他语言,首先要把源文件...

2019-09-05 10:49:52 139

原创 protobuf在windows环境下的使用

  在学习网络编程时,师兄给我提了个要求,让我用protobuf把字符串和图片打包发送,初次接触protobuf走了很多弯路,现在终于能够简单的使用,记录一下过程,希望能给遇到同样问题的同学一点帮助。  关于protobuf我就不多介绍了(我了解的也是皮毛,还在继续学习,哈哈哈哈哈~),使用环境:win10+VS2013,protobuf版本:2.6.1,文件已经上传到百度云,链接:https...

2019-08-28 17:07:18 357 2

原创 循环队列

  最近在项目中需要用到循环队列,发现自己很多地方还没理解透彻,因此梳理了一下相关知识,加深自己的理解。1.循环队列的概述  循环队列就是改进的顺序队列。我们在循环队列中设置两个指针,队尾指针rear指向刚进队元素的位置,队首指针front指向刚出队元素的位置。当元素进队时,rear要向后移动;当元素出队时,front也要向后移动;下图是循环队列元素进队/出队示意图:由空队进入三个元素,...

2019-08-28 13:45:58 3571

原创 C++中细节问题集合(持续更新)

1.如何理解p++?答:首先后置递增运算符的优先级高于解引用运算符,所以p++等价于*(p++)。p++把p的值加1,然后返回p的初始值的副本作为其求值结果,此时解引用运算符的运算对象是p未增加之前的值,最终,这条语句输出p开始时指向的那个元素,并将指针向前移动一个位置。2.new和malloc的区别答:new/delete是C++的运算符,malloc/free是C++/C语言的标准库...

2019-08-26 09:39:40 102

原创 TCP 客户端 、服务端的实现

  在很多工程中都需要用到信息的发送和接收,因此在网上收集了些资料,实现了简单的发送文字、文件、图片,以及BASE64编码。(TCP/IP,IP协议这里就不细说了,着重与功能的实现)套接字基础  套接字是一种网络API,可以使用它开发网络程序。套接字接口提供一种进程间的通信方法,使得在相同或不同的主机上的进程能以相同的规范进行双向信息传送。进程通过调用套接字接口来实现相互间的通信,而套接字接口...

2019-08-16 16:39:29 515

原创 C++多线程之互斥量

 在学习互斥量之前,我们要清楚什么情况下需要使用互斥量,第一个例子中有一段共享数据g_v,在main()函数中创建了10个线程,这10个线程的入口函数均为myprint(),在函数中打印出共享数据,代码如下:#include<map>#include<iostream>#include<thread>#include<list>#inclu...

2019-08-07 17:02:39 728

原创 临时对象作为线程参数

 detach()函数:在有多个线程的程序中,使用此函数后,主线程就不用逐个等待子线程结束,一旦调用detach,与这个主线程相关联的thread对象便会失去与这个主线程的联系,此时子线程就会驻留在后台运行,子线程就相当于被C++运行时库接管了,当子线程执行完毕后,由运行时库负责处理线程的习惯资源。 范例如下:#include<iostream>#include<threa...

2019-08-06 19:06:43 169

原创 OpenCV中saturate_cast模板函数的使用

背景 对图像进行点操作,来改变图像的亮度和对比度,原理如下图所示: 这里就出现了一个隐患,我们知道像素值的取值范围为(0,255),但按照上面的公式运算结果会超出取值范围,还有可能是非整数,所以需要用到saturate_cast模板函数,该函数的原理如下:if(data<0)data=0;else if(data>255)data=255;有了saturate_ca...

2019-07-22 14:46:11 1067

原创 从配置文件中读取数据--配置文件的创建,读取配置文件

  有时候把一些参数写在配置文件中,当需要修改这些参数时只需要在配置文件中修改即可,所以掌握如何使用配置文件很重要。第一步:写配置文件 先了解配置文件的格式,ini文件由 节、键、值组成。[section] --------------section处填写节的名字键=值 ------------------键代表参数的名字,值为参数的值…实例如下所示:可以看到该配...

2019-07-18 15:24:01 546

原创 C++中的文件操作

C++中的文件流类  在C++标准库中有三类可用于文件操作,称为文件流类:ifstream:用于从文件中读取数据ofstream:用于向文件中写入数据fstream:既可用于从文件中读取数据,又可向文件中写入数据  使用这三个类时,程序中需要包含fstream头文件,C++中各流类的关系如下图所示:open打开文件 在对文件进行读写操作之前,先要打开文件。通过打开文件,可以建立起...

2019-07-17 14:27:34 270

原创 对计算机中文件的理解

  在计算机中为了管理和检索数据引入了文件的概念,为了更好的使用文件,引入了文件夹(树形文件目录)。根据文件的功能不同可以将文件分为文本文件、视频文件、音频文件、图像文件、可执行文件等多种类别。这些文件实质上都是由一个个字节组成(0、1比特串),之所以呈现不同的形态是由文件的创建者和解释者约定的文件格式决定的。 例如常见的文本文件是指能够在记事本中打开,并且能看出是一段有意义的文字的文件,即文本...

2019-07-17 09:34:21 1416

原创 OpenCV--分离颜色通道&多通道颜色混合

split()  通道分离用到split()函数,该函数用于将多个通道数组分离成几个单通道数组,该函数的C++版本有两个原型:void split(const Mat& src,Mat*mvbegin);void split(InputArray m, OutputArrayOfArrays mv);  第一个参数,InputArray类型的m或者是const Mat&...

2019-07-15 15:19:43 169

原创 图像的线性混合操作

线性混合操作是中二元的像素操作,公式如下:在实现时可以用OpenCV中的addWeighted()函数,函数原型如下:void(InputArray src1,double alpha,InputArrary src2,double beta,double gamma,outputArray dst,int dtype=-1);参数1:InputArray类型的src1,表示要加权的第...

2019-07-15 13:45:26 244

原创 OpenCV中几个常用的绘图函数

通过一个小练习熟悉OpenCV中ellipse()函数、circle()函数,line()函数的使用。// #include<iostream>#include<opencv2/opencv.hpp>#include<opencv2/core/core.hpp>#include<opencv2/imgproc/imgproc.hpp>us...

2019-07-12 15:28:37 261

原创 OpenCV中常用的数据结构和函数

Point类:点的表示 Point类表示的是一个二维坐标下的点,其图像由其图像坐标X和Y指定的2D点。用法示例如下:Point point1,point2;point1.x=10;point.y=12;point2=Point(12,23); 另外,Point_,Point2i,Point互相等价,Point_,Point2f互相等价,因为查看OpenCV库中的core.hpp发现...

2019-07-12 11:34:33 266

原创 显式创建Mat

 Mat不仅是非常有用的图像容器类,也是一个通用的矩阵类 创建Mat对象可有以下方法:方法一:使用Mat()构造函数 例子如下:Mat M(2, 2, CV_8UC3, Scalar(0, 0, 255));在Mat类定义中该构造函数的原型为:Mat(int rows, int cols, int type,const Scalar& s);对于二维多通道图像,要...

2019-07-10 19:38:08 166

原创 基础图像容器Mat

简析 Mat类是用于保存图像以及其他矩阵数据的数据结构,默认情况下尺寸为0.当然我们也可以指定其初始尺寸

2019-07-10 16:09:43 98

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除