自定义博客皮肤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)
  • 收藏
  • 关注

原创 多路转接epoll原理详解

eventpoll结构体就是epoll模型,重点来看rdllist和rbr两个字段,rbr是一颗红黑树,节点存放了文件描述符和事件的映射关系,里面存放的都是用户传入的的文件描述符,而如果某个文件描述符上的事件就绪了,就会将这个节点插入到rdllist中。内核底层提供了一种回调机制,用于处理事件就绪时进行什么动作,默认这个回调是为空的,在epoll这里,这个回调被设置为当事件就绪后把节点插入就绪队列,于是,可以自动的在事件就绪时将节点插入就绪队列。为正数表示在timeout时间内事件就绪的文件描述符个数。

2025-04-24 18:01:44 774

原创 多路转接poll服务器

关于select的详解,可查看。

2025-04-22 21:18:18 576

原创 多路转接select服务器

前面介绍过多路转接就是能同时等待多个文件描述符,这篇文章介绍一下多路转接方案中的select的使用。

2025-04-22 19:46:03 893

原创 五种IO模型

一般系统提供的IO接口,实际上都在完成两件事,一件是等,等待数据就绪,如recvfrom会阻塞等待数据就绪,还有一件就是拷贝,把数据从内核缓冲区拷贝到用户缓冲区或者把数据从用户缓冲区拷贝到内核缓冲区。而可以想象,等待所消耗的时间肯定是远大于拷贝的时间,例如网络通信中大部分时间都消耗在等待上了,等待客户端的消息到达服务端,等待服务端的消息到达客户端。为了优化IO的效率,人们提出了五种不同的IO等待方式,这就是五种IO模型。

2025-04-16 16:16:59 550

原创 线程池设计

线程池实际上也是一个生产者消费者模型,线程池可以让多个线程去任务队列中取任务,执行任务,适用于需要大量的线程来完成任务且完成任务的时间较短。

2025-03-31 19:27:13 199 1

原创 信号量与基于环形队列的生产者消费者模型

信号量可用于线程间的同步,它可以用于将一整块资源切成一个个的小部分以供并发访问。它实际上是一个计数器,但特别之处在于支持原子性的++和--操作。在信号量中称为V操作和P操作举个电影院的例子来理解一下,电影院里有很多座位,而这些座位就相当于是整个电影放映会场所切成的小部分,以供多个观众进行预约。而观众关心的资源是座位,因此需要信号量来对剩余座位数计数,每有一个观众预约,这个信号量就--,减到0就阻塞住不再能预约,如果有观众退票,就将该信号量++,以便其他观众能再次预约座位。

2025-03-31 19:17:47 273

原创 Linux实现生产者消费者模型(基于阻塞队列)

生产者消费者模型是一种用于线程同步的模型,在这个模型中有两种角色,生产者生产数据,消费者消费数据。有三种关系,生产者与生产者,消费者与消费者,生产者与消费者。还有一个交易场所。超市就是生活中最常见的生产者消费者模型,工厂生产商品,超市充当缓冲区,消费者去超市消费同时取走超市中的商品。

2025-03-26 17:37:15 538

原创 Linux条件变量使用

条件变量用于线程间的同步,所谓同步就是使一些线程的执行按照时间先后进行。

2025-03-26 17:00:17 346

原创 Linux互斥量操作以及实现原理

试想现在有几个线程竞争锁,几个线程在执行xchgb前被切走,有一个线程a执行到了xchgb指令,现在它al寄存器与mutex交换,%al为1,mutex为0,如果执行完这条指令后其它线程占据了cpu,线程a被切走,a的上下文被保存起来,而上下文包括了%al的值。现在其他线程执行xchgb指令(抢占到cpu的线程也有自己的上下文,里面包含%al的值并且一定是0,因为movb指令将%al置为0),由于mutex已经被线程a改为0,所以此时,%al = 0, mutex = 0。

2025-03-23 19:19:35 289

原创 Linux线程库原理解析

我们知道在Linux中使用线程相关的函数时需要在使用gcc编译时带上-lpthread选项,这就是因为pthread一系列函数不是Linux提供的系统调用,而是一个库。下面来详细讨论一下这个库到底做了什么,它是如何给我们提供对线程的相关操作函数的。

2025-03-23 17:05:05 359

原创 Linux线程操作(创建,终止,等待,分离)

在使用Linux线程库时,需要包含头文件<pthread.h>,而且在链接时,需要包含-lphread选项。

2025-03-20 19:23:26 445

原创 C++11函数包装器

function是C++11引入的类,可以用任何可调用对象作为参数,构造出一个新对象。可调用对象有函数指针,仿函数,lambda等下面是function的声明可以看到是一个类模板,第一个参数是函数返回值类型,第二个是可变参数模板,表示函数的参数列表先看一个例子这是对lambda表达式的包装,关于lambda表达式,详见function可以将一系列参数列表和返回值相同的函数用相同的类型接收,这在某些情况下提供了极大的便利。

2025-03-16 18:20:58 909 1

原创 C++11 lambda表达式

lambda表达式实际上就是一种匿名函数,也就是说除了没有函数名,参数和返回值都有。

2025-03-16 16:30:49 791

原创 Linux网络套接字编程——UDP服务器

前面已经介绍了网络套接字的创建和绑定,这篇文章会通过UDP套接字实现一个UDP服务器。先介绍将使用的接口。

2025-03-13 20:28:29 530 1

原创 Linux网络套接字编程——创建并绑定

如果将进程比作一个房子,那套接字相当于是一扇门,通向与外界通信的通道。在网络中,如何理解套接字呢,时刻记住套接字是为了标识互联网中的某一台主机上的某一个进程,因此它就是IP地址 + 端口号。现在你完全可以把套接字当成一个结构体,里面包含了这台主机的IP地址和端口号。(只为了方便理解,实际中可能并不止如此)在介绍套接字前,先来认识一下网络字节序。

2025-03-13 18:59:24 783 1

原创 csapp笔记3.6节——控制(1)

文章一。

2025-02-03 22:34:29 352

原创 x86-64算术逻辑指令

对于大多数64位除法来说,被除数常常是64位的值,这个值应被存放在%rax(低64位)中,%rdx的值应该被设为全0(无符号除法)或全符号位(有符号除法)。二元操作第一个是源,第二个既是源又是目的,类似C语言+=运算符,第一个操作数可以是立即数、寄存器、内存位置,第二个操作数可以是寄存器和内存位置。除了leaq,其他算数指令都有大小变种,leaq第一个操作数是一个地址,将这个地址复制到第二个操作数中,实际上该指令并不会引用内存,不会管这个地址处存的什么值,只是单纯将这个地址赋值给第二个操作数。

2025-02-02 22:19:54 488

原创 x86-64数据传输指令

关于汇编语言一些基础概念的更详细的介绍,可移步该指令集中一个字2字节。该架构有16个64位寄存器,名字都以%r开头,每个寄存器的都可单独拿出来使用。如下图当指令以寄存器为目标时,对于生成小于八字节的结果的指令,有两条规则:生成1、2字节的保持高位不变;生成4字节的把高四字节置为0。这些寄存器中最特别的是栈指针%rsp,用来指明运行时栈的结束位置。在过程的实现中,这个寄存器很重要。

2025-02-01 23:20:28 475

原创 csapp2.4节——浮点数

但对于0.101010,它若要舍入到小数点后四位,有两个方向,0.1010和0.1011,算出0.101010与这两个数的差的绝对值是相同的,说明四位后是中间值,这时采用向偶数舍入的策略,选择0.1010。下面举个例子来理解编码,例如十进制小数3.75,转化为二进制小数为11.11,我们要将它表示为一个float类型的数,也就是说有8位阶码,Bias=127,23位小数字段。对于n位小数字段,在规格化表示下,只存储了小数点右边的值,在计算最终值时再加上1,因为左边的值恒为1,这样可多一位精度。

2025-01-25 21:46:33 843

原创 csapp笔记——2.3节整数运算

对于的整数x,y,定义表示将x与y的和截为w位由此推得检测无符号加法是否溢出得方法是判断结果是否比x,y中的任何一个小。无符号数的逆元定义为使得的y,若x为0则y为0,否则,y为。

2025-01-23 21:18:21 507

原创 csapp笔记——2.2节整数表示

这节很有意思的点在于将整数的编码用数学的语言描述,这样从数学角度思考能更好的理解补码的作用,补码的一些好用的性质,也更加严谨。

2025-01-20 19:49:57 924

原创 MIPS指令集(一)基本操作

这种指令格式在某些场景可能不适用,如lw指令需要传入偏移量,5位是不够用的,这时,想要增加位数,但是MIPS的设计是,所有指令的长度都相同,这样,就会采取折中方案:所有指令长度相同,但不同类型指令采用不同指令格式。机器指令分为多个字段,本例第一个和最后一个告诉MIPS计算机要执行加法操作,第二个和第三个表示源操作数寄存器,第四个字段表示存放结果的寄存器,第五个字段没有用到,故置为0。(add immediate),常数操作数出现频率高,像这种带立即数的指令,比从存储器种取值快很多,能耗也较低。

2024-12-17 22:36:04 1288

原创 C++入门篇(5)——类和对象(2)

如果一个类一个成员都没有,那么这个类就是空类。但空类并非什么都没有,编译器会对任何一个类都生成六个默认成员函数。

2024-02-15 12:57:07 576 8

原创 C++入门篇(4)—— 类与对象(1)

class className //指定想要的类的名字// 类体:由成员函数和成员变量组成// 一定要注意后面的分号这 就是类的定义方式。类体中内容称为类的成员:类中的变量称为类的属性或成员变量;类中的函数称为类的方法或者成员函数。类中的函数有两种定义方式1.直接在类中定义函数,但需要注意,这样编译器可能将该函数视为内联函数。2.类中函数声明,在类外定义函数。在类外定义函数需要注意成员函数名前加上类名。int _year;int _month;int _day;

2024-02-10 20:12:33 2647 6

原创 C++入门篇(3)auto关键字、内联函数、nullptr关键字

这种情况下一行中的变量必须是同一个类型,否则会报错。注意:auto使用时必须初始化,因为编译器需要根据初始化的数据类型确定出auto的实际类型。

2024-02-06 12:31:15 989 7

原创 C++入门篇(2)函数重载、引用

C++函数重载和引用

2024-02-04 10:56:22 1032 3

原创 C++入门篇(1)命名空间、输入输出函数、缺省参数

若有函数声明,则缺省参数只能出现在函数声明中,不能出现在函数定义中。必须像这样,不能声明定义都出现缺省参数,只能有声明出现缺省参数。

2024-02-02 22:59:12 492 4

原创 控制台简易程序——贪吃蛇

在控制台中实现一个简易的贪吃蛇小程序,蛇体可用●代替,作为边界的墙体用□表示,食物用★表示。最终效果如下同时实现蛇的移动,吃食物的反馈,以及游戏结束条件判断。

2024-01-31 22:14:45 3115 5

原创 结构体基础回顾

结构是⼀些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。这个结构体的类型就是struct stu,要用该结构体声明变量时,要使用struct stu声明。要访问结构体中的成员,需使用'.'操作符或者这么写。

2023-12-04 14:28:53 420 1

原创 整数和浮点数在内存中的存储

整数在存储成二进制数时,二进制数的最高位是符号位,为0时表示正整数,为1时表示负整数。

2023-12-03 22:58:30 79 2

原创 C语言内存函数

该函数作用类似于strcpy,函数声明如下从source地址拷贝num个字节的数据到destination地址处,这个函数强大之处在于不限制数据类型,可以是整型,浮点型,也可以是结构体。用法如上。结果是但是这个库函数,在C语言该函数是处理两块内存空间没有重合的情况,也就是说像这种用法尽量避免。但是也许在你的编译器上他是可以正常运行,这个可能是因为你所使用的编译器对其进行了优化。

2023-11-30 22:19:12 59

原创 指针知识点归纳

cpu如果想要访问某一块内存空间,就需要让cpu知道这是哪一块内存空间,由此需要对内存进行编址,将内存划分为一段段的小空间。指针变量就是接收这种地址编号的变量。cpu和内存之间传递数据,可以理解为用“线”来传递。简单理解,32位机器有32根地址总线,每根线表达“电脉冲有无”也就是0,1。因此32位机器上给内存编号,最多有32个bit位,也就是4字节。同理64位机器上编号最多为64字节。所以在32位机器上,指针变量大小为4字节,64位机器上,指针变量大小为8字节。

2023-11-25 16:04:35 126 4

原创 能排序任意数据类型数组的冒泡排序的实现

C语言中有一个库函数qsort,可以实现对任意类型数组进行排序,其函数声明如下其中base是数组首元素地址,num是无符号整型,意为数组元素个数,size是数组元素中每个元素的大小,单位为字节,而最后一个是一个函数指针,指向的函数会告诉计算机比较两元素的方法,比如比较两个结构体的大小,不能直接想1<2那样简单的直接比较,可以根据结构体中的元素进行比较,比如这个结构体,可以比较age得出两个结构体之间的大小关系,也可以比较name字符串得出二者大小关系。

2023-11-24 12:33:39 79 1

原创 C语言统计整型数组中每个元素出现次数

给定一个整型数组,可以先将其排序再用一个两列的二维数组存放每个数以及出现的次数。count数组中确实存放了1以及1出现的次数。

2023-11-23 12:14:55 1258

原创 一道很离谱的坑题

事实上,这道题的情况非常特殊,因为i的地址恰好与arr[0]的地址相差12,而其他很多情况下,i与arr[11]之间会有空隙,这样都无法造成死循环的结果。而这种巧合的出现,是依赖于VS2022、X86、Debug这种特定的环境。可以看到bug的产生是多么无孔不入,但凡换个环境,都不会死循环。

2023-11-12 21:56:04 110 3

原创 如何输入带空格的字符串

C语言中可以用%s格式来输入字符串,但是他却不能输入带空格的字符串,一旦scanf读入到了空格,就会停止读入,像这样。这样就能输入带空格的字符串,只不过我们的这个字符串结尾是空格不是反斜杠零。虽然输入了ad 21,但是读到空格就结束了。可以用下面的代码解决。

2023-11-12 21:01:44 500

原创 写个简易控制台阉割版扫雷游戏

接下来问题是如何统计一个位置周围雷的个数,一种方法可以是,遍历这个位置周围的元素,若为'1',则加1,这种方法还需要判断这个位置是否在边界,比较麻烦。我们知道'1'-'0'==1,'2'-'0'==2,字符1减字符0等于数字1,那么我们只用计算'0'周围'1'数量就可以了,将选择的位置周围元素全部相加再减去7*'0',就得到了周围的雷数。接下来会在里面随机的生成若干个雷,并且需要统计某个'*'周围的雷个数。这样的'0','1'棋盘与'*'棋盘中的'*'一一对应,可以得出每个'*'周围的雷数。

2023-11-01 21:24:14 102 1

原创 C语言分支循环语句

这段代码想表达的是c不等于+,-,*,/中的任何一个时就是取余运算,但是,最后效果并非如此,else会与离else最近且未匹配的if匹配,所以这题输入不是'/'就会走else。后跟一条语句即可,需要注意的是,if后只有一条语句会生效,如果要使多个语句生效,需要使用{}将语句括起来。有一点要注意,当有多个if语句并列时,else会与离else最近且未匹配的if匹配,比如。if(表达式)表达式结果为真就执行下面的语句,为假则不执行,0为假,非0为真。就像这样,c被赋值了'w',但也输出了余数。

2023-10-25 14:36:24 106 2

原创 unsigned char可以匹配的占位符

unsigned char的大小为一个字节,想让它输入或输出一个整型可以使用%hhu,%hhu的大小是一个字节。

2023-10-18 16:30:41 230 1

原创 辗转相除法

两个数a,b,用a除以b,再把b赋给a,余数赋给b,重复直至余数为0,则此时除数就是两个数的最大公因数,代码如下。辗转相除法可以用来计算两个数的最大公因数。

2023-10-12 20:30:45 103

空空如也

空空如也

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

TA关注的人

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