- 博客(81)
- 收藏
- 关注
原创 【Linux】Reactor反应堆模式
Reactor 模式是一种事件驱动的编程模式,用于高效的处理并发I/O操作。它通过一个或多个事件循环(Event Loop)来监听和处理各种事件(如网络请求、定时器事件等),从而实现高效的并发处理,而无需为每一个连接创建一个线程或进程。OneThreadOneLoop(OTOL)是一种设计模式,通常用于描述基于事件驱动编程(注意:管道也能线程间通信,所以我们可以使用同样的方法进行设计。如果不想使用管道,可以使用其他做法。)的架构,特别是在使用异步I/O(),从而实现高效的并发处理。
2025-11-06 21:28:58
618
原创 【Linux】多路转接epoll
这里暂时未考虑 listen_socket ET 的情况,如果将 listen_socket 设为ET,则需要非阻塞轮询的方式accept,否则会导致同一时刻大量客户端同时连接的情况,只能accept一次的情况。如果服务端写的代码是阻塞式的read,并且一次只read 1K的数据(read不能保证一次就把所有数据都读出来,参考man手册上的说明,可能被信号打断),剩下的9K数据就会待在缓冲区中。但是在LT情况下,也能做到每次就绪的文件描述符都立刻处理,不让这个就绪被重复提示的话,其实性能也是一样的。
2025-11-02 22:48:59
893
原创 【Linux】多路转接select
理解select模型的关键在于理解fd_set,为说明方便,取fd_set长度为1字节,fd_set中的每一bit可以对应一个文件描述符fd。则一字节长的fd_set最大可以对应8个fd。当只检测文件描述符0(标准输入)时,因为输入条件只在你有输入信息的时候才成立,所以如果一直不输入,就会产生超时信息。timeval结构用于描述一段时间长度,如果在这个时间内,需要监视的描述符没有事件发生则函数返回,返回值是0。感兴趣可以了解一下。提供了一组操作fd_set的接口,来比较方便的操作位图。
2025-11-01 22:57:14
822
原创 【Linux】五种IO模型与非阻塞IO
而且在实际的应用场景中,等待消耗的时间往往远高于拷贝消耗的时间。让IO更高效,最核心的方法就是让等待的时间尽量少。这个同步,是同步通信异步通信的同步,还是同步与互斥的同步。这里的同步通信和进程之间的同步是完全不相干的概念。这五种IO分别是:阻塞IO、非阻塞IO、信号驱动IO、多路转接/多路复用IO、异步IO。:内核将数据准备好的时候,使用SIGIO信号通知应用程序进行IO操作。阻塞和非阻塞关注的是程序等待调用结果(消息,返回值)时的状态。传入的cmd的值不同,后面追加的参数也不同。
2025-10-31 23:21:23
737
原创 【Linux】NAT,代理服务,内网穿透
正向代理(Forward Proxy)是一种常见的网络代理方式。它位于客户端和目标服务器之间,代表客户端向目标服务器发送请求。正向代理服务器接收客户端的请求,然后将请求转发给目标服务器,最后将目标服务器的响应返回给客户端。通过这种方式,正向代理可以实现多种功能,如提高访问速度,隐藏客户端身份,实施访问控制等。反向代理服务器是一种网络架构模式。其作为Web服务器的前置服务器,接收来自客户端的请求,并将这些请求转发给后端服务器,然后将后端服务器的响应返回给客户端。
2025-10-31 00:06:17
692
原创 【Linux】数据链路层
虽然我们在这里介绍ARP协议,但是需要强调,ARP不是一个单纯的数据链路层的协议,而是一个介于数据链路层和网络层的协议。MTU相当于发快递时对包裹尺寸的限制。这个限制是不同的数据链路层对应的物理层,产生的限制。使用ifconfig命令,即可查看IP地址,MAC地址和MTU。由于数据链路层MTU的限制,对于较大的IP数据包要进行分片。ARP协议建立了主机IP地址 和 MAC地址的映射关系。用于两个设备(同一种数据链路节点)之间进行传递。
2025-10-29 19:31:48
1059
原创 【Linux】网络层协议IP
真实的网络结构非常复杂,即涉及到划分公网IP的组织,ICANN,还要在全球范围内进行区域划分,比如亚太,北美,欧洲等,又要考虑到国家内部的ISP代理,整体拓扑非常复杂,我们简化所有过程,简单理解公网即可。如果一个组织内部组建局域网,IP地址只用于局域网内的通信,而不直接连到Internet上,理论上,使用任意的IP地址都行,但是RFC 1918规定了用于组建局域网的私有IP地址。CIDR在一定程度上缓解了IP地址不够用的问题(提高了利用率,减少了浪费,但是IP地址的绝对上限并没有增加),仍然不是很够用。
2025-10-28 22:59:50
3174
原创 【Linux】传输层协议TCP
为什么TCP这么复杂?因为要保证可靠性,同时还要尽可能提高性能。校验和序列号(按需到达)确认应答超时重发连接管理流量控制拥塞控制滑动窗口快速重传延迟应答捎带应答定时器(超时重传定时器,保活定时器,TIME_WAIT定时器等)
2025-10-26 23:13:59
914
原创 【Linux】应用层协议HTTP
无论是HTTP 301还是HTTP 302重定向,都需要依赖Location这个选项来指定资源新的位置。这个Location选项是一个标准的HTTP响应头部,用于告诉浏览器应该将请求重定向到哪个新的URL地址。
2025-10-24 23:44:07
1427
1
原创 【Linux】应用层自定义协议与序列化
toStyledString、StreamWriter 和FastWriter 提供了不同的序列化选项,你可以根据具体需求选择使用。Json::Reader 和 parseFromStream 函数是 jsoncpp 中主要的反序列化工具,它们提供了强大的错误处理机制。在进行序列化和反序列化时,请确保处理所有可能的错误情况,并验证输入和输出的有效性。
2025-10-20 23:32:46
996
原创 【Linux】Socket编程TCP
原型:int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);原因:是因为我们 accept 一个请求后,就一直在 while 中循环尝试 read,没有继续调用 accept,导致无法接受新的请求。返回值:成功返回实际发送的字节数(可能小于len),失败返回-1并设置errno。功能:用于客户端套接字发起连接请求,目标是与指定服务器建立可靠的TCP连接。返回值:成功返回接收到的字节数,失败返回-1并设置errno。
2025-10-20 12:06:46
819
原创 【Linux】Socket编程UDP
功能:创建通信端点(套接字)。AF_INETAF_INET6AF_UNIXSOCK_DGRAM返回子:成功返回套接字描述符;失败返回 -1 并设置 errno。功能:将套接字(socket)绑定到特定的本地 IP 地址和端口号上。原型:int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);返回值:成功返回 0;失败返回 -1 并设置 errno。
2025-10-18 16:49:48
1016
原创 【Linux】网络基础概念
TCP/IP协议本质是一种解决方案。TCP/IP协议能分层,本质是问题本身能分层。截至目前,我们还没有接触过任何协议,但是如何朴素理解协议,我们已经可以试试了。OS源代码一般都是用C/C++语言写的。问题:主机B能够识别data,并且准确提取出a = 10, b = 20, c = 30吗?回答:答案是肯定的。因为双方都同样的结构体类型struct protocol。也就是说,用同样的代码实现协议,用同样的自定义数据类型,天然就具有“共识”,能够识别对方发来的数据,这不就是约定吗?
2025-10-14 21:58:54
885
原创 【Linux】进程间同步与互斥(下)
IT行业这么火,涌入的人很多。俗话说林子大了什么鸟都有,大佬和菜鸟的两极分化越来越严重,为了让菜鸡们不太拖大佬的后腿,于是大佬们针对一些经典的常见的场景,给定一些对应的解决方案,这个就是。
2025-10-12 22:13:57
1007
原创 【Linux】线程同步与互斥(上)
生产者和消费者之间不直接通讯,而是通过阻塞队列进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里获取。当队列满时,从队列中存放元素的操作会被阻塞,直到有元素从队列中取出(以上的操作都是基于不同的线程来说,线程在对阻塞队列操作时会被阻塞)。当线程1解锁后,系统唤醒在锁上挂起的线程,但是线程1解锁后立刻抢了锁,而其他线程还刚被唤醒,又被挂起等待,所以导致只有线程1在执行,其他线程一直挂起。功能:等待信号量,表示要使用资源了,会将信号量值 -1。
2025-10-10 23:39:57
1023
原创 【Linux】线程概念与控制
在一个程序里的一个执行路线就叫做线程(thread),更准确的定义是:线程是“一个进程内部的控制序列”。一切进程至少都有一个执行线程。线程在进程内部运行,本质是在进程地址空间内运行。在Linux系统中,在CPU眼中,看到的PCB都要比传统得进程更加轻量化。透过进程虚拟地址空间,可以看到进程的大部分资源,蒋进程资源合理分配给每个执行流,就形成了线程执行流。
2025-10-09 22:22:50
896
原创 【Linux】Linux进程信号(下)
在内存资源上的使用,操作系统对内核态和用户态也做了限制,每个进程创建都会分配虚拟地址空间,以Linux32位操作系统为例,它的寻址空间范围是 4G(2的32次方),而操作系统会把虚拟空间地址划分为两部分,一部分为内核空间,一部分为用户空间,高位的 1G(从虚拟地址 0xC0000000 到 0xFFFFFFFF)由内核使用,而低位的 3G(从虚拟地址 0x00000000 到 0xBFFFFFFF)由各个进程使用。如果信号的处理动作是用户自定义的函数,在信号递达时就调用这个函数,这称为捕捉信号。
2025-10-07 23:16:20
1093
1
原创 【Linux】Linux进程信号(上)
这个类型可以表示每个信号的 “有效” 或 “无效” 状态,在阻塞信号集中 “有效” 和 “无效” 的含义是该信号是否被阻塞,而在未决信号集中 “有效” 和 “无效” 的含义是该信号是否处于未决状态。阻塞信号集也叫做当前进程的。除零异常后,我们并没有清理内存,关闭进程打开的文件,切换进程等操作,所以CPU中还保留上下文数据以及寄存器内容,除零异常会一直存在,就有了我们看到的一直发送异常信号的现象。从上图来看,每个信号只有一个 bit 的未决标志,非0即1,不记录该信号产生了多少次,阻塞标志也是这样表示的。
2025-10-06 17:42:50
688
1
原创 【Linux】System V —— 基于建造者模式的信号量
目录一、信号量和P、V原语1.1 信号量常规理解1.2 信号量值含义1.3 信号量结构体伪代码1.4 P原语1.5 V原语1.6 信号量集结构体二、信号量操作接口2.1 semget2.2 semctl2.3 semop三、封装Sem信号量和P、V原语由Dijkstra(迪杰斯特拉)提出。1.4 P原语1.5 V原语1.6 信号量集结构体二、信号量操作接口2.1 semget参数介绍:参数介绍:1. semid:2. semnum:3. cmd:控制命令常用命
2025-10-04 23:02:35
1136
原创 【Linux】进程间通信 —— System V
一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再设计到内核,换句话说进程不再通过执行进入内核的系统调用来传递数据了。SHM_RND标志,则连接的地址会自动向下调整为SHMLBA的整数倍。注意:共享内存段不是必须手动删除,这里只是演示,应该由进程删除IPC资源。shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY。返回值:成功返回一个非负整数,即该共享内存段的标识码;注意:将共享内存段与当前进程脱离并不表示删除该共享内存段。shmid:由shmget返回的共享内存标识码。
2025-10-04 14:54:11
590
原创 【Linux】进程间通信——管道
数据传输:一个进程需要将它的数据发送给另一个进程。资源共享:多个进程间共享同样的资源。通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。
2025-10-03 23:26:53
559
原创 【Linux】库的链接与加载
静态链接的出现,提高了程序的模块化水平。对于一个大的项目,不同的人可以独立的测试和开发自己的模块。通关静态链接,生成最终可执行文件。我们知道静态链接会将编译产生的所有目标文件,和用到的各种库合并为一个独立的可执行文件,其中我们会去修正模块间函数的跳转地址,也叫做编译重定位(静态重定位)。而动态链接实际上将链接的整个过程推迟到了程序加载的时候。
2025-09-29 23:34:45
1016
原创 【Linux】库制作与原理
库是写好的,现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都是从零开始,因此库的存在意义非同寻常。本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存中运行。静态库:.a【Linux】,.lib【Windows】动态库:.so【Linux】,.dll【Windows】// ubuntu 动静态库// C//C++int flag;// 刷新⽅式int fileno;// ⽂件描述符int cap;
2025-09-27 17:55:45
699
原创 【Linux】Ext系列文件系统(下)
我们看到,真正找到磁盘文件的并不是文件名,而是 inode。其实在Linux上可以让多个文件名对应一个 inode。myfile5和myfile5_1的链接状态完全相同,它们被称为指向文件的硬链接。内核记录了这个链接数,557299的硬链接数为2。我们再删除文件时干了两件事:1. 在目录中将对应的数据清除;2. 将硬链接 - 1,如果为0,则将对应的磁盘释放。
2025-09-24 22:48:35
721
1
原创 【Linux】Ext系列文件系统(上)
磁盘:磁盘是计算机存储数据的基本硬件设备,通常分为机械硬盘(HDD)和固态硬盘(SSD)。磁盘直接安装在服务器或存储设备中,用于存储操作系统、应用程序和用户数据。磁盘的性能和容量直接影响服务器的数据处理能力。服务器:服务器是一种高性能计算机,用于处理数据、运行应用程序和提供服务。服务器通常包含多个磁盘、CPU、内存和网络接口,能够执行复杂的计算任务。服务器可以独立运行,也可以集群化部署以提高性能和可靠性。机柜:机柜是用于集中安装和管理服务器的物理框架,通常为标准19英寸宽度。
2025-09-22 21:17:23
798
原创 【Linux】基础IO
pathname: 要打开或创建的目标文件flags: 打开文件时,可以传入多个参数选项,用下面的一个或者多个常量进行“或”运算,构成flags。参数:O_RDONLY: 只读打开O_WRONLY: 只写打开O_RDWR : 读,写打开这三个常量,必须指定一个且只能指定一个O_CREAT : 若文件不存在,则创建它。需要使用mode选项,来指明新文件的访问权限O_APPEND: 追加写返回值:成功:新打开的文件描述符失败:-1。
2025-09-21 18:04:51
603
原创 【Linux】进程控制
这里,我们思考一下函数和进程之间的相似性。exec/exit就像call/return一个C程序由很多函数组成。一个函数可以调用另一个函数,同时传递给它一些参数。被调用的函数执行一定的操作,然后返回一个值。每个函数都有它的局部变量,不同的函数通过call/return系统进行通信。这种通过参数和返回值在拥有私有数据的函数间通信的模式是结构化程序设计的基础。Linux鼓励将这种运用与程序之内的模式扩展到程序之间。如下图:一个C程序可以fork/exec另一个程序,并传递给它一些参数。
2025-09-18 00:10:54
1018
原创 【Linux】进程概念(下)
计算机在给程序分配内存时会采取这样的方法:先将内存中的前10M分配给程序A,接着再从内存中剩余的118M中划分出110M分配给程序B。在早期的计算机中,要运行一个程序,会把这些程序全都装入内存,程序都是直接运行在内存上的,也就是说程序中访问的内存地址都是实际的物理内存地址。我们发现,输出出来的变量值和地址是一模一样的,原因很简单,子进程以父进程为模板,且父子并没有对变量进行任何修改。上面的图就足以说明问题,同一个变量,地址相同,其实是虚拟地址相同,内容不同,其实是被映射到了不同的物理地址!
2025-09-15 00:02:45
1045
原创 【Linux】Linux进程概念(上)
计算机管理硬件描述起来,用struct结构体组织起来,用链表或者其他高效的数据结构在系统当中查找一个最合适调度的进程的时间复杂度是一个常数,不随着进程的增加而导致时间成本增加,我们称之为进程调度O(1)算法/**/#endif/**/#endif#endif/**/
2025-09-13 22:35:06
709
原创 【Linux】Linux环境基础开发工具使用
1. 三种模式命令模式插入模式末行模式2. vim操作打开,关闭,查看,查询,插入,删除,替换,撤销,复制等等操作。
2025-09-06 20:31:16
1257
原创 【Linux】Linux权限
目录的可执行权限是表示你可否在目录下执行命令。如果目录没有-x权限,则无法对目录执行任何命令,甚至无法cd 进入目, 即使目录仍然有-r 读权限(这个地方很容易犯错,认为有读权限就可以进入目录读取目录下的文件)而如果目录具有-x权限,但没有-r权限,则用户可以执行命令,可以cd进入目录。但由于没有目录的读权限所以在目录下,即使可以执行ls命令,但仍然没有权限读出目录下的文档。
2025-09-04 23:04:49
1404
原创 【Linux】Linux下基本指令
你看上了小花,但是有不好意思直接表白,那就让你你家人找媒婆帮你提亲,所有的事情你都直接跟媒婆沟通,由媒婆转达你的意思给小花,而我们找到媒婆姓王,所以我们叫它王婆,它对应我们常使用的bash。cp指令用于复制文件或目录,如同时指定两个及以上的文件或目录,且最后的目的地是一个已存在的目录,则它会把前面指定的所有文件或目录都复制到此目录中。,我们操作windows 不是直接操作windows内核,而是通过图形接口,点击,从而完成我们的操作(比如进入D盘的操作,我们通常是双击D盘盘符.或者运行起来一个应用程序)。
2025-09-03 21:56:27
1099
原创 【C++】C++的IO流
在C语言中,如果想要将一个整型变量的数据转换成字符串格式,如何去做?使用itoa()函数使用fprintf()函数但是两个函数在转化时,都需要先给出保存结果的空间,那空间要给多大呢,就不太好界定,而且转化格式不匹配时,可能还会得到错误的结果甚至程序崩溃。在C++中,可以使用stringstream类对象来避开此问题。在程序中如果想要使用stringstream,必须要包含头文件 <sstream>。
2025-08-31 12:36:38
863
原创 【C++】C++的类型转换
每次使用强制类型转换前,程序员应该仔细考虑是否还有其他不同的方法达到同一目的,如果非强制类型转换不可,则应限制强制转换值的作用域,以减少发生错误的机会。RTTI:Run - time Type identification的简称,即:运行时类型识别。因此C++提出了自己的类型转换风格,注意因为C++要兼容C语言,所以。
2025-08-20 23:48:31
950
原创 【C++】特殊类设计
如果单例对象构造十分耗时或者占用很多资源,比如加载插件,初始化网络连接,读取文件等等,而有可能该对象程序运行时不会用到,那么也要在程序一开始就初始化,就会导致程序启动时非常慢。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理。设计模式是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。:就是说不管你将来用不用,程序启动时就创建一个唯一的实例对象。
2025-08-18 23:34:01
899
原创 【C++】智能指针
什么是内存泄漏:内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。内存泄漏的危害:长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现内存泄漏会导致响应越来越慢,最终卡死。// 1.内存申请了忘记释放// 2.异常安全问题Func();// 这里Func函数抛异常导致 delete[] p3未执行,p3没被释放.
2025-08-18 00:00:01
712
原创 【C++】异常
实际使用中很多公司都会自定义自己的异常体系进行规范的异常管理,因为一个项目中如果大家随意抛异常,那么外层的调用者基本就没办法玩了,所以实际中都会定义一套继承的规范体系。这样大家抛出的都是继承的派生类对象,捕获一个基类就可以了。throw Student("该学生不是这个学校的", 3);
2025-08-16 23:15:56
1100
原创 【C++】C++11相关内容
在2003年C++标准委员会曾经提交了一份技术勘误表(简称TC1),使得C++03这个名字已经取代了C++98称为C++11之前的最新C++标准名称。不过由于C++03(TC1)主要是对C++98标准中的漏洞进行修复,语言的核心部分则没有改动,因此人们习惯性的把两个标准合并称为C++98 / 03标准。从C++0x到C++11,C++标准10年磨一剑,第二个真正意义上的标准珊珊来迟。
2025-08-16 00:19:51
606
原创 【C++】哈希的应用:位图和布隆过滤器
我们在使用新闻客户端看新闻时,它会给我们不停地推荐新的内容,它每次推荐时要去重,去掉那些已经看过的内容。一种支持删除的方法:将布隆过滤器中的每个比特位扩展成一个小的计数器,插入元素时给k个计数器(k个哈希函数计算出的哈希地址)加一,删除元素时,给k个计数器减一,通过多占用几倍存储空间的代价来增加删除操作。比如:删除上图中"hello"元素,如果直接将该元素所对应的二进制比特位置0,“world”元素也被删除了,因为这两个元素在多个哈希函数计算出的比特位上刚好有重叠.给40亿个不重复的无符号整数,没排过序。
2025-08-13 22:36:12
919
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅