自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 boost::asio网络编程

boost::asio提供了同步和异步的connect、read、write函数。这些函数有2套实现,一个是出错时抛异常,一个是传入错误码boost::asio::ip提供了对ip地址、端点的封装,当创建套接字时需要传入io_context,并提供了套接字属性控制函数(类似fcntl)cmake构建时需要的组件 boost::system boost::regex。

2024-07-24 10:19:26 931

原创 使用c++函数式编程实现Qt信号槽机制

6:上述代码main函数中connect时传入的lambda表达式,下面在Signal中将其封装为bind方法,并提供对应的connect函数,使其更类似于Qt信号的connect。在下面的代码中,Input输入器 输入数据,希望A和B 接收数据。但使用的赋值,导致in.a和a只是拷贝数据,而不是同一个对象,使得数据不同步。解决方法1:如下所示,当希望修改in.a的age时能修改到A a的age,需要传指针A,而且还要手动指定in.a = &a。5:为了信号更加通用,使用变长模板参数来实现。

2024-07-04 21:01:43 244

原创 Linux内核编译流程

内核在启动初始化过程中会解压缩initrd文件,然后将解压后的initrd挂载为根目录,然后执行根目录中的/init脚本,您就可以在这个脚本中运行initrd文件系统中的内核模块自动加载机制udevd,让它来自动加载realfs(真实文件系统)存放设备的驱动程序,以及在/dev目录下建立必要的设备节点。将内核中的proc文件系统挂载到/proc文件夹,这样就可以通过访问/proc下的文件和目录,获取到与内核和系统相关的信息。3.init进程使用根文件系统下的/init脚本来继续启动系统。

2024-06-25 20:56:04 1105

原创 缓冲池管理器

克隆cd bustub/切换分支创建docker镜像创建容器启动容器查看有哪些已经启动的容器docker ps进入指定容器。

2024-06-25 20:53:19 719

原创 未定义行为总结

因为其中使用了__restrict关键字,告诉编译器该指针与其它指针是相互独立的,不会重叠,便于编译器进行优化。malloc产生的指针只保证对齐到max_align_t,而new能保证对齐到alignof(T)下面的代码尽管能正常运行,但c->fun()等价于(*c).fun(),也就是对空指针解引用了。T类型的指针必须对齐到alignof(T),构造未对齐的指针属于未定义行为。解引用空指针,例如解引用空的this指针、解引用空的函数指针。从语法上来说,移动过的对象是可以访问的,但不要这样做。

2024-06-20 16:58:20 457

原创 避免指针成员重复释放

拷贝构造和移动构造函数都删除掉,传参的时候用unique_pointer包装一下,因为独占指针是可以移动的。此时指针指向的资源不可移动,指针可以移动。在下面的代码中,类A保存有1个指针,并且理所当然的在构造函数中分配内存,析构中释放内存,但会发生重复释放的问题。原因:编译器自动生成如下的拷贝构造(析构函数不影响拷贝操作的自动生成,只会影响移动操作的自动生成)因为:移动构造和移动赋值相互影响 移动操作和拷贝操作相互影响。解决方法1:显式的删除拷贝构造函数,然后使用时传引用。智能指针的深拷贝怎么写。

2024-06-18 16:43:39 165

原创 面向对象的设计原则、设计模式

在一开始的数据求和案例中,使用init虚函数顶替了数据初始化,但实际上求均值等更复杂的操作中需要初始化不止一个数据(还需要记录数字总个数),解决方法如下:使用工厂模式。注意到:StopInputerAdapter本身也是Inputer,可以直接作为fun的参数,适应现有策略模式。依赖倒置:fun函数不直接依赖于 数据处理、数据获取 的细节,而是依赖于其抽象类。给适配器的策略模式 使用 适配器:组合不同策略,形成区间。单一职责:Inputer负责数据的处理方式。给适配器使用策略模式:用虚函数顶替阈值判断。

2024-06-04 14:54:32 936

原创 Effective Modern C++阅读笔记

charstrerror(interrnum)接收一个错误码,返回错误信息s)先打印字符串s,再根据当前errno打印信息。

2024-04-03 10:17:35 833

原创 RPC 框架-格式化输出、eventfd、Reactor模式、linux定时器、XML文件的使用

通过网络调用远程计算机的服务,主要用于分布式系统内部。由于单纯使用TCP会导致粘包问题,因此需要在应用层对数据进行封装用于区分消息边界,例如在应用层使用HTTP协议或RPC协议。RPC协议的诞生比HTTP早。服务发现:找到服务对应的ip地址和端口 的 过程。http中是通过DNS服务解析域名得到ip地址,而rpc有专门的中间服务保存服务名和ip信息(例如redis)。主流的http1.1使用json序列化结构体数据,而rpc定制化程度更高,使用protobuf序列化协议。

2024-01-16 22:14:14 1550

原创 C/C++实现线程池、C++20信号量std::counting_semaphore

为了各线程安全访问共享资源,如忙线程数量、当前存活线程数量,需要使用互斥锁,并使用条件变量实现生产者消费者模型。为了管理者能让工作线程自杀,在工作线程阻塞被唤醒后,会对exitNum值进行判断,来决定是否线程自杀。pthread_create创建出一个管理者线程、多个工作线程,并将线程ID存放在数组中。循环读取任务队列,如果没任务了且线程池没关闭,那么就阻塞。为了管理者能够合理对线程数进行调整,需要记录当前当前存活的线程数与忙线程数。只要线程池没关闭,就每隔3秒检测一次,添加或减少工作线程数。

2023-11-29 16:55:04 1610 1

原创 linux网络编程

connect是进行三次握手,对于非阻塞的client,connect返回-1不一定是connect失败,需要看errno,如果errno是EINPROGRESS,表示三次握手还在进行,尚未完成连接的建立。此时需要监听fd可写事件,等到可写了就去获取fd的errno,如果errno为0,表示没有错误,连接建立成功了。连接:客户端的端口是由系统默认自动分配的空闲端口,connect处指定的是服务器的端口。设置sockaddr_in结构体。

2023-11-17 20:14:59 71

原创 在c++中使用Protobuf序列化结构化数据

编译proto,⽣成C++⽂件:对于每个 .proto ⽂件⽣成 .h 和 .cc ⽂件,分别⽤来存放类的声明与类的实现。字段唯⼀编号的范围:1 ~ 2^29-1,其中 19000 ~ 19999不可⽤。注意:结构体的编号是从1开始,而enum枚举的第一个编号必须是0。使用:编译时要链接protobuf库。先写两个proto文件如下。

2023-11-14 20:52:14 193

原创 编译期检测所有未定义行为和内存泄漏、类型转换、虚函数表、奇异递归模板模式

左移只能左移0-31位int main()return 0;数组越界a + 33;//越界了,虽然没使用这个结果 g++不报错,clang报错//a+32是可以获取但不能访问的,这是为了便于数组遍历。而a+33是不能获取也不能访问的忘记delete:因此constexpr可以检测是否发生内存泄漏重复delete未初始化push_back导致迭代器失效。

2023-11-13 20:28:04 49

原创 c++17内存池与多态分配器std::pmr::memory_resource

sort 传入2个迭代器对象(左闭右开)和一个比较函数(默认升序),首先调用上述的混合排序函数__introsort_loop(__first, __last, 栈深, __comp),这个函数内有个while循环,当元素个数小于等于16才会退出。:主要采用快速排序,但是快速排序如果枢纽没选好,会导致递归深度很大,为了避免这种情况,当递归深度达到一定次数,就不会继续递归下去了,而是转用堆排序。:memory_resource是一个抽象类,其有具体的实现函数,不要直接使用memory_resource。

2023-11-06 22:50:54 530

原创 C++11的特性

shared_lock的lock是共享锁定的,unique_lock的lock是排他锁定的,因此,一般像下面这样使用。如果一个类使用的构造析构移动拷贝赋值都是默认的,且没有虚函数,也没有虚基类,那么就是平凡的类型…std::weak_ptr:弱引用的智能指针,它不共享指针,不能操作资源,是用来监视shared_ptr的。在传绑定的参数时,如果想传引用,必须使用ref包起来,如果想传const引用,使用cref。,该锁有普通的排他性锁定lock(),也有共享锁定lock_shared()

2023-10-30 22:34:39 44

原创 使用__PRETTY_FUNCTION__获取模板参数的类型、静态for循环、常量值类型std::integral_constant、c++14有哪些新特性

打印日志#include <iostream>//__PRETTY_FUNCTION__会打印整个函数签名#define LOG(x) (std::cout<<__FILE__<<" : "<<__LINE__<<" : "<<(x)<<" 调用的函数名:"<<__func__<<std::endl)int main(){ std::cout<<"当前路径和文件名:"&l

2023-10-30 22:04:15 176

原创 现代CMake的配置与构建、示例模板、动态链接库、find_package、缓存变量、添加伪目标来启动程序、目录组织方式、更新CMake

PROJECT_SOURCE_DIR与CMAKE_CURRENT_SOURCE_DIR的区别:如果当前CMake里没有project指令,那么就找当前的上一层,如果上一层有,那么PROJECT_SOURCE_DIR是上一层的所在目录。由于option和set设置缓存变量是一个意思,也会存在 第一次编译把变量缓存起来,下一次直接使用缓存变量 的问题,因此,会出现修改了OFF为ON,但没反应的现象。当找不到名为xx的局部变量时,会去缓存里找,有的变量是通过-D参数固定到缓存里的。

2023-10-27 21:51:26 820

原创 缓存的工作机制

1次浮点数的读写时间约等于做32次浮点加法的时间(因为从内存读写数据实在太慢了),得益于cpu的预取机制,1次浮点读写+0次加法 与 1次浮点读写+32次加法 的时间差不多,它在做a[i]的加法计算时,同时会开始预取a[i+1]的数据。因此,每次至少读取64字节数据,即使只想读取4字节数据,也会将该地址周围整个64字节数据读取到缓存。cpu试图写入4字节数据时,由于缓存和内存通信的最小单位是缓存行(64字节),因此缓存会先从内存读取64字节数据,然后修改其中的4字节为cpu给的数据,之后择机写回。

2023-10-23 21:52:10 73

原创 reduce、transform_reduce、decltype、函数式编程、SIMD、TBB并发

如果不是4的倍数,例如1023,那么会将1020个元素用SIMD填入,剩余的3个元素使用传统标量方式填入,为了实现这样的功能,编译器会生成很复杂的边界特判代码。对于没有声明为__restrict的两个指针,编译器担心它们重叠,会同时生成两份代码,一份是SIMD的,一份是传统标量的,运行时判断指针的差值是否超过1024来判断重叠。计算数组内浮点数的和时,由于temp越加越大,如果是串行着累加,就会导致 大加小 丢失精度,而如果使用并行的累加,每次相加的就都是一个数量级的,会更精确。

2023-09-27 10:45:58 284 1

原创 CTAD(类模板实参推导)、推导指引、enable_if_t、is_same、requires

同理还有,is_null_pointer_v、is_integral_v、is_lvalue_reference_v、is_const_v等等。**更隐蔽的易错点:**如果是想判断数组的元素是不是int,也需要使用std::decay_t。细节2:decltype推导类型会推导出&和const,因此下面这样写无论如何都是进else分支,导致报错。细节1:为了避免报错,需要编译期就不编译到return t+1,因此下面使用constexpr。,其返回的是引用类型,即int&enable_if_t的使用。

2023-09-19 21:50:25 164

原创 log4cpp日志库的使用

其下脚本会在用户登录时自动执行,具体而言,/etc/profile文件会遍历profile.d文件夹下的所有脚本并执行。它们都由内存管理类自动管理释放,其会找到category下的appender的layout,关闭日志:可以不手动调用,HierarchyMaintainer会在程序结束时自动调用。在new创建appender对象时,使用不同的函数,则日志输出的地方会不同。打印日志:日志优先级 不低于 Category的优先级时 才输出。不要手动释放Category、Appender和Layout,

2023-09-17 22:17:33 108 1

原创 libevent库的使用

创建事件和事件集合、绑定事件、添加事件到集合、开启监听。而在使用套接字通信时,事件的创建、绑定和添加步骤被自动执行。不用创建事件,有专门的函数自动在连接成功时将cfd加入事件集合。完整代码:编译时要加-levent。

2023-09-14 15:11:18 86 1

原创 Qt读写json、套接字通信、多线程、条件变量、QList、QFileDialog文件浏览、QDir目录操作、QListWidget

使用E:\az\Qtfolder\5.12.9\mingw73_32\bin下的windeployqt.exe。为了避免文件传输过程中,某些字符在不同平台转码不一样,导致错误。主线程中创建线程对象、创建任务对象、移动任务对象到子线程中、启动子线程、调用任务函数。为了避免主线程直接调用任务函数导致阻塞,可以使用信号来通知子线程启动。方法1:简单,run不能带参数,子线程只能通过信号传递参数。创建一个manager对象,用于做get、post请求。为了使用线程池,消费者任务对象继承自QRunnable。

2023-08-28 19:49:33 263 1

原创 右值引用与完美转发、变长模板参数与折叠表达式、variant的使用、tuple的使用

问:说一个c++11提出的非常重要的概念右值引用:用来延长右值的生命周期,还实现了与之相关的移动语义和完美转发,许多常用容器都已经实现了移动构造和移动赋值。

2023-08-16 21:02:14 82 1

原创 CMakeLists练习

对之前单例模式的代码进行重写,来学习cmake的使用第一种尝试:整个项目的所有设置都写在一个CMakeLists.txt中不是所有预处理器都支持#program once,因此这里写成防卫式声明的样子将类单独写成.h和.cppmain子线程的函数也同样拿出来单独写成.h和.cpp在build目录下写CMakeLists.txt第二种尝试:为每个模块(库)编写独立的CMakeLists.txt文件最外层CMakeLists.txt那么在子模块中,是怎么生成动态库的呢。

2023-08-15 22:12:19 228 1

原创 单例模式的使用

双检查锁也有问题:m_instance = new Singleton处会出现问题:正常以为的顺序是先分配内存、再调用构造器初始化一些值,最后将该内存指针返回。但由于编译器优化的原因,有可能会先分配内存并返回指针,最后才调用构造器。这样导致线程B可能拿到的是未调用过构造器的m_instance,对象的状态是不对的。先判断是否已创建过实例对象,如果没创建过就加锁,加锁以后再检查一次是否创建过,避免在加锁前其它线程也通过了第一个判断在锁前等待,导致其它线程获得锁以后也能创建一个实例。

2023-08-14 22:44:27 44

原创 【无标题】练习使用fastcgi时报错upstream prematurely closed FastCGI stdout while reading response header from ups

浏览器访问时报错upstream prematurely closed FastCGI stdout while reading response header from upstream。

2023-08-10 21:59:41 300 1

原创 写一个处理用户注册json信息的fastcgi程序

目标:读取数据并对注册数据进行检验,查询mysql数据库看用户是否已存在,不存在则将用户信息插入到数据库中。最终需要返回一个{“code”:“002”}的json字符串表示注册成功。背景:客户端通过post请求将用户注册信息以json的格式传送给nginx服务器,服务器将此请求转交给如下fastcgi程序来处理。

2023-08-08 22:31:16 84

原创 Nginx和fastDFS的整合

浏览器作为客户端,在访问http://192.168.232.132/group1/M00/00/00/wKjohGTDg3eAQx09ADYDn-wridU777.jpg时,将命令发送到了nginx服务器(注意,这是原来的存储节点上安装了带插件的nginx)80端口,命令匹配/group1/M00/。

2023-08-02 20:39:26 309 1

原创 Linux多线程开发

当A线程已经加读锁成功,线程B想加写锁,同时线程C想加读锁:由于读写不同时,因此线程B和C都阻塞。当线程A解锁后,由于优先写,线程B加写锁成功,而线程C继续阻塞。为什么需要互斥锁:因为同一进程下的线程共享同一份全局内存区域,为了避免访问冲突,需要使用互斥锁来进行同步。在此情况下,如果线程A先抢到cpu:先加锁,发现不满足条件会马上解锁,然后阻塞等待线程B。什么是读写锁:是一把锁,读共享,写独占,读写不同时,优先写。测试程序:主线程先执行,直到i

2023-08-01 16:03:35 36 1

原创 fastCGI的安装与使用

请求的url:http://localhost/login?当客户端点击上传时报错,报错信息在/usr/local/nginx/logs/error.log中,在其中就能看到出错时的请求行是什么。命令(/login):去掉协议、域名IP、端口,尾部有文件名则去掉,去掉?传输大文件,多个数据块。

2023-07-28 10:25:33 1112 1

原创 nginx的安装与使用

如果make时报错 error: this statement may fall through [-Werror=implicit-fallthrough=] 37 | h ^= data[2]

2023-07-27 15:12:15 48 1

原创 redis的使用与数据结构

由于压缩列表的entry节点中会保存前一个entry节点的长度,当长度较小时使用1字节来表示,长度较大时使用5字节,如果前entry节点长度变化剧烈,会导致多个entry的prevlen字段需要扩容,也就是发生了连锁更新。当字符串长度较小时,使用嵌入式字符串编码(embstr),将字符串内容直接存放在redis对象的内存结构中,只需要一次内存分配,但如果字符串需要增加长度,就需要重新分配redis对象的内存,因此embstr 实现为只读,一旦进行了修改,就会变为使用raw编码。使用快速列表进行编码。

2023-07-25 22:38:20 259

原创 FastDFS文件上传详细步骤

配置文件默认位置: /etc/fdfstracker 配置文件storage 配置文件客户端配置文件。

2023-07-25 11:21:40 2259

原创 Linux多进程开发

首先,创建一个itimerval结构体,在其中指定定时器的启动延时与信号发送间隔时间。然后,setitimer()使用定时器。接着,创建sigaction结构体,在其中指定信号处理函数。最后,sigaction()放置信号捕捉。

2023-07-24 23:37:58 94

原创 浏览器怎样将信息发送给web服务器

a) 浏览器对URL进行解析,确定了web服务器和文件名,生成HTTP请求信息a) 调用Socket库中的解析器程序,传入(域名,Class,记录类型),解析器据此生成查询信息b) 查询信息被操作系统的协议栈程序发送给邻近的DNS服务器i. 怎样委托协议栈发送消息:1. 客户端调用Socket库中的socket创建套接字,协议栈返回一个描述符2. 调用Socket库中的connect(描述符,服务器IP,端口号80)进行连接:a) 客户端将自身IP、端口等控制信息告知协议栈b) 客户端将自身IP

2023-07-19 19:58:26 463

原创 WSL报错Temporary failure resolvin

然后在这个新建的文件里粘贴下面。

2023-07-10 22:19:54 159 1

Arbitrary-scaleSuper-resolutionviaDeepLearning:AComprehensiveSur

一篇任意尺度的综述

2024-03-15

ffmpeg_version.cmake

4.x版本 CMake编译OpenCV时出现 CMake Warning at cmake/OpenCVDownload.cmake:202 (message): FFMPEG: Download failed: 6;"Couldn't resolve host name", 需要下载本文件替换到 opencv\sources\.cache\ffmpeg。使用cmake-gui命令打开Cmake,重新进行编译即可成功

2022-09-07

空空如也

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

TA关注的人

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