自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Qt 多线程

QThreadmoveToThreadQThreadPoolQRunnableConcurrentQFuture

2024-07-23 19:01:33 110

原创 c++左值和右值,左值引用和右值引用

所以右值引用既可能是左值,又可能是右值吗?确实如此:右值引用既可以是左值也可以是右值,如果有名称则为左值,否则是右值;这同样也符合前面章节对左值,右值的判定方式:其实引用和普通变量是一样的, int &&ref = std::move(a) 和。引用是变量的别名,由于右值没有地址故没法修改,所以左值引用没法指向右值;同样的,右值引用能指向右值。引用本质是别名,可通过引用修改变量的值,传参时传引用可以避免拷贝;,本质上也是把右值提升为一个左值,并定义一个右值引用通过。能指向左值,不能指向右值的就是左值引用;

2023-12-16 12:21:30 861

原创 Qt信号和槽

Qt信号和槽实际上就是23种设计模式中的观察者模式;当某个事件发生了就会发出信号,处理信号和自己的函数称为槽绑定来处理这个信号;信号的本质就是事件;信号和槽的优点:类型安全,松散耦合;一个类型若要支持信号和槽,则必须从QObject或QObject的子类继承,信号和槽机制不支持对模板的使用;通过Qobject::connect函数连接信号和槽对应的对象,该函数是一个回调函数并被注册到Qt中;1)多线程的情况下,信号需要排队等待;4)需要定位接受信号的对象;2)编组和解组传递参数;3)安全的遍历所有关联;

2023-12-10 14:36:18 383

原创 nginx

http请求与nginx建立连接后,nginx会为该连接分配内存池,每个连接建立时内存池分配,每个连接断开时内存池销毁;互联网应用最外层的网关,域名后面对应的80端口用的就是nginx,nginx做代理服务器,其后面连接不同的服务器,比如存储,直播,录播等;nginx相比apache,代码风格是纯c的,版本迭代很频繁,提供的文档资料齐全,容易编译应用,跨平台;ngx_str, list, queue, hash, arrary, log, 原子操作,共享内存,线程池,内存池,红黑树,http协议。

2023-12-01 14:37:52 398

原创 C++设计模式

2、设计原则:1)依赖倒置,接口的使用者不要依赖具体的实现,而应该依赖具体接口;1)开闭原则,对扩展开放,对修改关闭,主要针对封装和多态;3)封装变化点,主要针对封装和多态;比喻:整洁的房间,有一个好动的猫,怎么保证房间的整洁?定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤;设计模式是指在软件开发中,经过验证的,用于解决在特定环境下,重复出现的,特定问题的解决方案;稳定点是算法骨架,变化点是子流程需要变化;

2023-11-14 21:31:35 47

原创 git问题

安装 sudo apt-get -y install build-essential nghttp2 libnghttp2-dev libssl-dev。git clone报错;git clone正常。

2023-09-04 23:13:31 70

原创 mysql缓存策略

mysql主从复制中,从数据库会主动和主数据库建立连接,建立连接后会产生log dump thread线程,该线程从binlog读数据并发送到从数据库;热点数据放到redis中,服务器读数据的时候从redis中读,如果不是热点数据依然从mysql读;读策略,在server层写逻辑,如果是热点数据则从redis中读数据,如果不是热点数据则从mysql中读数据;读写分离,分担读写压力,因为读的操作较多,所以直接往从数据库中读,写的操作较少,所以直接操作主数据库;2)mysql没有数据,redis中有;

2023-08-31 23:53:57 46

原创 mysql事务原理分析

元数据锁用于数据在修改的时候不能让其他连接修改这个表的结构,一个在修改表结构,一个在修改数据,这两者是冲突的,所以要添加元数据锁;3)隔离性,acid中最重要的一个特性,通常是由原子性,一致性,持久性一起来实现的;在这多个并发处理的事务中,可能乱序交叉执行,我们需要解决这乱序交叉执行的问题,让数据库知道接下来的语句是一个事务;2)一致性,数据库完整约束的一致性,还有唯一约束,非空约束,外键约束等,这些约束在事务的操作过程中到操作结束,它的一致性不会受到影响;全局锁,用于锁数据库,整个库是可读的状态;

2023-08-31 21:49:05 38

原创 mysql索引原理以及sql优化

按照主键构建的B+树,叶子节点中存放数据页,数据也是索引的一部分;free list组织buffer pool中未使用的缓存页,flush list组织buffer pool中脏页,也就是刷盘的页,lru组织buffer pool中冷热数据,当buffer pool没有空闲页,将lru list中最久未使用的数据进行淘汰;change buffer用来缓存二级索引,如果是辅助索引的修改会先在change buffer中修改,change buffer的数据会异步刷新到buffer pool中;

2023-08-31 15:25:13 34

原创 sql语句,索引,视图,存储过程

删除数据有三种方式,drop删除整张表,表结构和表数据,包括索引,约束,触发器等,速度最快,不能回滚;mysql内部执行方式,网络处理模型使用了io多路复用select+阻塞io,每条线程处理一条连接的数据,所以mysql命令处理是多线程并发处理的模式,线程的默认配置最大数为151;是一个长期存储在计算机内的,有组织的,可共享的,统一管理的大量数据的集合;DDL是数据定义语言简称,即create创建,alter修改,drop删除表,试图,数据库对像等;去除重复,合并重复,通过聚合函数实现;

2023-08-30 21:14:01 51

原创 redis主从同步与对象模型

依然由主从关系,但这里由多个主节点,通常取奇数个主节点,这些节点之间构成了一个系统;aof是拿单个数据进行持久化,而rdb是拿所有数据进行持久化,所以如果主进程宕机了,那么rdb丢数据是丢得最多的,所以我们要在可靠性和效率之间做一个平衡,所以就有一种rdb-aof的持久化方式,部分使用rdb持久化,部分使用aof持久化;这里client至少要建立两条连接,一条是需要和哨兵节点建立连接监听主从切换的消息,哨兵节点选取了主redis后,会通知client,一条是和主redis建立的连接;redis持久化方式。

2023-08-30 19:30:32 45

原创 redis存储原理和数据模型

通过redis-server redis-conf启动redis服务,启动后的redis-server是主线程,bio_close_file线程用来关闭大文件,redis是内存数据库,当我们需要将内存数据刷新到磁盘中,redis中有种方式是fork一个进程并在子进程中进行持久化,持久化工程中会产生rdb的文件,rdb文件中存储着内存中的数据,如果rdb是个大文件,就会涉及关闭大文件的问题;rehash的规律,经过rehash后,ht[0]中0位置的数据要么在ht[1]中0位置,要么在ht[1]中4位置;

2023-08-30 13:01:28 89 1

原创 redis协议与异步方式

redis网络层中,假设有三个client与服务器建立连接,reactor会管理对应的连接,通过事件循环不断的处理连接给服务器发送的数据,现在只关注数据包处理的流程,这里有三个管道,车子比做网络线程,网络线程不断地从管道中取数据包,分割数据包,decode,compute,encode,最后发送到client端;微观抽象的redis网络,由io多路复用+非阻塞io组成,有io检测和io操作的职责,有异步事件处理流程,先注册事件,在事件循环中处理事件;a是原子性,c是一致性,i是隔离性,d是持久性;

2023-08-30 01:10:27 96 1

原创 redis相关命令详解及其原理

set无序集合结构,对顺序不关注,里面的值都是唯一的;有序集合zset结构,对顺序是关注的,里面的值是唯一的,根据member来确定唯一,根据score来确定有序;在二进制字符串的实现中,我们是以长度进行分割的,所有sdshdr8结构中有个len标记二进制字符串的长度,alloc是分配的长度频繁分配内存,flags说明字符串类型,比如长度是32,还是64;redis是数据结构数据库,也就是kv中的v提供了丰富的数据结构,包括string,list,hash,zset,set;2)关注命令的返回具体值;

2023-08-29 13:35:40 90

原创 应用层协议设计ProtoBuf/Thrift

4、在序列化后的buffer前面增加一个字符流的头部,其中有个字段存储消息总长度,根据特殊字符如\n或\0判断头部的完整性,http和redis采用的时这种方式,收到消息的时候,先判断已收到数据中是否包含结束符,收到结束符后解析消息头,解出这个消息完整长度,按此长度接收消息体;3、固定消息头+消息体结构,这种结构中一般消息头部分是一个固定字节长度的结构,并且消息头中会有一个特定的字段指定消息体的大小,收到消息时,先接收固定字节数的头部,解析这个消息的完整长度,按此长度接收消息体。

2023-08-29 08:44:21 79 1

原创 异步日志方案log4cpp

服务器程序支持每个模块都有独立日志输出,比如epoll+线程池,这里epoll属于io模块,线程池属于业务处理模块,不同模块对应不同的category,layout是格式化输出;log4cpp日志框架适合使用在客户端中,不适合使用在服务器,在服务器中没办法做到高性能;批量写入会少调用write接口,也少调用fsync接口;fwrite应用层库接口,会调用write接口,write是linux系统接口;树状功能:所有的模块输出都打印到root中,对应输出文件;日志格式化,通过自定义格式供选择。

2023-08-28 11:50:18 208 1

原创 libevent/libev框架实战

因为write实际做的工作不是在用户态完成的,而是在内核态完成的,所以要通过int 0x80中断切换到内核态,内核会把要运行的上下文加载到cpu的寄存器上,接下来调用就进入了内核内部,内核内部会调用sys_write函数,sys_write是根据系统调用号找到向量表,从向量表中查找sys_write函数,就开始执行该函数,执行sys_write函数时分阻塞io和非阻塞io,阻塞io可能还会引起线程切换;reactor的主体思想是将网络io的处理转化为对事件的处理,事件分为读事件和写事件;

2023-08-27 19:09:19 95 1

原创 分布式锁实现

我们需要S1,S2,S3,S4进程和含有lock锁的进程建立连接,我们操作lock锁资源都是网络交互进行的,通过发送命令,返回锁是否操作成功的信息;2)锁超时,在分布式场景中,所资源与进程行为是分离的,通过网络交互进行锁操作,这种情况下有lock资源的机器可能宕机,操作锁的进程所在机器也可能会宕机,这就要考虑一种情况,比如S1进程持有锁了,S2,S3,S4都在等待锁的释放,如果此时S1进程持有锁,但是含有S1进程的机器宕机了,由于加锁对象和解锁对象必须为同一个,在这种情况下S1进程就不能主动释放锁了;

2023-08-27 10:50:32 55 1

原创 c/c++ 内存泄漏检测

5)老版本接口,别攻击的很重要的点,即__malloc_hook,是一种指针的方式;系统提供了一个指针,每一次调用malloc函数的时候,底层会调用到__malloc_hook指针,这个指针是固定的值;对于线上系统是需要重启的,如果不重启可以通过热更新,在.conf文件中加入mtrace;思路和hook是一样的;运行上图程序得到mem.txt文件如下,通过+和-的匹配情况判断是否有内存泄漏;1)虚拟内存在涨的时候,我们不确定是程序的需要还是内存泄漏;2、如何判断内存泄漏,哪个地方的代码实现导致内存泄漏;

2023-08-25 19:15:56 508 1

原创 死锁检测组件实现

死锁的状态,是由于线程无法正常获取资源;如下1,2,3,4代表资源,A,B,C,D代表线程,开始1,2,3,4分别被A,B,C,D线程使用着,但是此时A又需要使用2,B需要使用4,C需要使用1,D需要使用3;以邻接表,若线程1申请线程2的资源,而该资源又被线程2占用着,我们就将线程1的next指针指向线程2,表示线程1生成的资源已经被线程2占用了;当线程多了之后,一部分线程做数据处理,一个线程做日志同步,还有做网络的线程及操作数据库的线程,当线程比较多的时候出现死锁的概率是很高的;

2023-08-25 17:07:08 42 1

原创 无锁消息队列

通过ypipe_t和yqueue_t两个类实现无锁队列;从zeromq最快的无锁队列;1、链表的方式实现无锁队列、数组的方式实现无锁队列。2)在同步机制上的争抢队列。5、为什么需要无锁队列。

2023-08-25 15:28:18 36 1

原创 锁和原子操作CAS的底层实现

在linux内核中没有进程线程之分,统一叫做task_struct,当调用pthread_create函数时,创建task_struct,创建这个结构体后的状态是new,就绪,等待,执行,退出都是线程的状态;上面代码中,cpu_set_t设置cpu组,这里时4个cpu,然后通过CPU_ZERO把mask清空,然后对进程self_id取模并使用这个值对mask对应位置1;通过cpu_set_t做粘合,比如4个cpu,进程或线程需要绑定哪个cpu,就将cpu_set_t对应位设置为1;如何解决上述问题呢?

2023-08-24 15:05:00 40 1

原创 gdb调试

/1. 设置:set scheduler-locking off。// 1. 设置:set scheduler-locking on。//4.切换线程:thread n(n代表第几个线程)//1.查看进程:info inferiors。//1. 设置断点:break 行号/函数名。//2.查看线程:info threads。//2. 查看断点:info b。//查看主线程和新线程的关系。//3.查看线程栈结构:bt。// 2. 运行:n。// 2. 运行:n。//查看当前运行的进程。

2023-08-24 10:22:47 82 1

原创 内存池的实现与分析

每个节点同样占4k内存,链表中的节点存放了该节点的4k内存中未使用的空间的起始地址和结束地址,用户需要分配比4k小的内存时,从对应节点的4k内存中按地址顺序获取未分配的内存,并修改该节点的4k内存中未使用的空间的起始地址;堆上的内存,栈是不能被操作的,共享内存段mmap这块内存空间;我们说的内存池是对堆上的内存进行管理;由于分配内存大小是不确定的,什么时候分配是不确定的,所以导致内存池针对不同场景实现的多样性;1)分配的大块内存占4k空间,并通过large指针以链表的形式串连起来;物理内存是接触不到的;

2023-08-24 00:22:08 57 1

原创 mysql和redis连接池

比如cpu可以同时并发128个线程,任务是部分需要操作数据库,部分不需要操作数据库的,通常同时操作数据库有64个线程,那么我们就把最小连接数设置为64,最多同时操作数据库为128个线程,那么我们就把最大连接数设置为128;比如,连接池创建了4个连接,保持线程池模块连接到数据库中,如果线程池需要操作数据库做任务,那么只需要从连接池获取连接,每个连接只能同时给一个任务用。长连接是一些驱动,驱动框架、ORM工具的特性,由驱动来保持连接句柄的打开,以便后续数据库操作可以重用连接,从而减少数据库连接的开销;

2023-08-23 21:39:50 67

原创 线程池与性能

线程池

2023-08-23 17:20:43 45

原创 linux内存不足,调整swap空间

2023-07-24 14:27:00 45

原创 linux命令

grep -r "***" ./ //在当前目录下的所有文件中查找***字符串,并将含有***字符串的文件名列出;

2023-07-13 16:57:21 30 1

原创 LLVM编译源码

【代码】LLVM编译源码。

2023-07-08 16:24:17 318

原创 百万并发服务器

百万并发服务器

2023-02-13 13:19:48 131 1

原创 Linux编译内核

linux内核编译

2022-09-12 11:46:41 2373 1

空空如也

空空如也

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

TA关注的人

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