- 博客(54)
- 收藏
- 关注
原创 Linux文件系统(三)
打开当前目录,查看当前目录的内容,可当前目录也是文件,访问当前目录也是只知道文件名,要访问当前目录,也得知道当前目录的inode号,所以还需要打开当前目录的上一级目录,于是,类似递归的,把所有目录全部解析,递归出口是 "/"目录。我们访问文件通常使用的是文件名而不是inode号,所以操作系统必须能够记录下两者的映射关系,由于文件都是属于目录的,所以这个映射关系是由 目录记录的,目录的文件数据就是inode号和文件名的映射关系。访问文件,必须加上路径,而根目录的inode号无需查找,系统开机后就知道。
2025-07-27 19:36:06
339
原创 Linux文件系统(二)
我们想要在硬盘上储⽂件,必须先把硬盘格式化为某种格式的⽂件系统,才能存储⽂件。⽂件系统的⽬的就是组织和管理硬盘中的⽂件。没有它就不能访问硬盘里的文件ext2将整个分区划分为同样大小的块组(Block Group),只要能管理好一个块组,就能管理整个分区,也就能管理好整个磁盘上图中启动块(Boot Block/Sector)的⼤⼩是确定的,为1KB,由PC标准规定,⽤来存储磁盘分区信息和启动信息,任何⽂件系统都不能修改启动块。启动块之后才是ext2⽂件系统的开始。
2025-07-27 17:55:13
672
原创 linux文件系统(一)
磁盘由一个个盘面组成,每个盘面上的一个个圆环就是磁道(cylinder),再将磁道分为一个个的扇区(sector),扇区就是磁盘存储数据的最小单位,大小通常为512字节,磁头(header)就是用来读写数据的。柱面是分区的最小单位,柱⾯⼤⼩⼀致,扇区个位⼀致,那么其实只要知道每个分区的起始和结束柱⾯号,知道每⼀个柱⾯多少个扇区,那么该分区多⼤就知道了。Linux下,保存⽂件属性的集合叫做inode,⼀个⽂件,⼀个inode,inode内有⼀个唯⼀的标识符,叫做inode号。”块”是⽂件存取的最⼩单位。
2025-07-27 17:12:05
966
原创 TCP详解——各标志位
送的窗⼝,所以拥塞窗口会控制发送窗口的大小,初始是1,只发送一个数据段,收到应答后变为2,这里假设接收端的接收能力强,一直大于拥塞窗口大小,接着会发送两个数据段,在一个RTT(往返时间)内,会收到两个ACK应答,那么拥塞窗口加2,变为了4。所以,一直维护拥塞窗口的大小(尤其是增大)是有意义的,尽管它变大到一定值不再对发送窗口的大小产生影响,但是持续增大他,可以使下次超时重传的阈值更大,使发送速度更加贴合网络的情况。URG为1时,紧急指针就指向了紧急数据,紧急数据很多时候都只有一个字节,用来传递某些信息。
2025-07-12 19:33:08
968
原创 TCP详解——流量控制、滑动窗口
窗口内的数据段都有可能丢,我们不妨先来回忆一下确认应答号的定义,确认应答号为i表示1~i-1的数据全部收到了,把left赋值为i,表示1~i-1的数据全收到了,如果i <= right,可以看出丢包了,那么i~right的每一个数据段,都有可能丢包了,但是,我们只需要处理最左边的数据段,即以left为开头的第一个数据段,把它重发即可。所谓窗口,就是你写算法题经常遇到的那个滑动窗口。这个窗口内所维护的就是待发送的数据段,窗口左边是确认收到应答的数据段,窗口右边就是以后再发的数据段。
2025-07-12 00:06:51
1121
2
原创 TCP协议详解——初识
这篇文章是初识,先理解部分字段的作用源和目标端口号意义明确。序列号和确认应答号后面再展开数据偏移字段是4位,意义是表明TCP首部有几个4字节,图上可以看出来一行是32bit也就是4字节,这个4位数据偏移字段相当于表明了有几行,由此可以算出TCP首部最大时4 * 15 = 60个字节控制位有8位,但是很多时候把前两位与保留位合并,之后的6位每个位表达不同的含义,从左到右依次是URG: 紧急指针是否有效ACK: 确认号是否有效PSH: 提⽰接收端应⽤程序⽴刻从TCP缓冲区把数据读⾛。
2025-07-11 19:47:23
711
原创 多路转接epoll原理详解
eventpoll结构体就是epoll模型,重点来看rdllist和rbr两个字段,rbr是一颗红黑树,节点存放了文件描述符和事件的映射关系,里面存放的都是用户传入的的文件描述符,而如果某个文件描述符上的事件就绪了,就会将这个节点插入到rdllist中。内核底层提供了一种回调机制,用于处理事件就绪时进行什么动作,默认这个回调是为空的,在epoll这里,这个回调被设置为当事件就绪后把节点插入就绪队列,于是,可以自动的在事件就绪时将节点插入就绪队列。为正数表示在timeout时间内事件就绪的文件描述符个数。
2025-04-24 18:01:44
803
原创 五种IO模型
一般系统提供的IO接口,实际上都在完成两件事,一件是等,等待数据就绪,如recvfrom会阻塞等待数据就绪,还有一件就是拷贝,把数据从内核缓冲区拷贝到用户缓冲区或者把数据从用户缓冲区拷贝到内核缓冲区。而可以想象,等待所消耗的时间肯定是远大于拷贝的时间,例如网络通信中大部分时间都消耗在等待上了,等待客户端的消息到达服务端,等待服务端的消息到达客户端。为了优化IO的效率,人们提出了五种不同的IO等待方式,这就是五种IO模型。
2025-04-16 16:16:59
567
原创 线程池设计
线程池实际上也是一个生产者消费者模型,线程池可以让多个线程去任务队列中取任务,执行任务,适用于需要大量的线程来完成任务且完成任务的时间较短。
2025-03-31 19:27:13
213
1
原创 信号量与基于环形队列的生产者消费者模型
信号量可用于线程间的同步,它可以用于将一整块资源切成一个个的小部分以供并发访问。它实际上是一个计数器,但特别之处在于支持原子性的++和--操作。在信号量中称为V操作和P操作举个电影院的例子来理解一下,电影院里有很多座位,而这些座位就相当于是整个电影放映会场所切成的小部分,以供多个观众进行预约。而观众关心的资源是座位,因此需要信号量来对剩余座位数计数,每有一个观众预约,这个信号量就--,减到0就阻塞住不再能预约,如果有观众退票,就将该信号量++,以便其他观众能再次预约座位。
2025-03-31 19:17:47
294
原创 Linux实现生产者消费者模型(基于阻塞队列)
生产者消费者模型是一种用于线程同步的模型,在这个模型中有两种角色,生产者生产数据,消费者消费数据。有三种关系,生产者与生产者,消费者与消费者,生产者与消费者。还有一个交易场所。超市就是生活中最常见的生产者消费者模型,工厂生产商品,超市充当缓冲区,消费者去超市消费同时取走超市中的商品。
2025-03-26 17:37:15
565
原创 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
302
原创 Linux线程库原理解析
我们知道在Linux中使用线程相关的函数时需要在使用gcc编译时带上-lpthread选项,这就是因为pthread一系列函数不是Linux提供的系统调用,而是一个库。下面来详细讨论一下这个库到底做了什么,它是如何给我们提供对线程的相关操作函数的。
2025-03-23 17:05:05
376
原创 Linux线程操作(创建,终止,等待,分离)
在使用Linux线程库时,需要包含头文件<pthread.h>,而且在链接时,需要包含-lphread选项。
2025-03-20 19:23:26
458
原创 C++11函数包装器
function是C++11引入的类,可以用任何可调用对象作为参数,构造出一个新对象。可调用对象有函数指针,仿函数,lambda等下面是function的声明可以看到是一个类模板,第一个参数是函数返回值类型,第二个是可变参数模板,表示函数的参数列表先看一个例子这是对lambda表达式的包装,关于lambda表达式,详见function可以将一系列参数列表和返回值相同的函数用相同的类型接收,这在某些情况下提供了极大的便利。
2025-03-16 18:20:58
929
1
原创 Linux网络套接字编程——UDP服务器
前面已经介绍了网络套接字的创建和绑定,这篇文章会通过UDP套接字实现一个UDP服务器。先介绍将使用的接口。
2025-03-13 20:28:29
547
1
原创 Linux网络套接字编程——创建并绑定
如果将进程比作一个房子,那套接字相当于是一扇门,通向与外界通信的通道。在网络中,如何理解套接字呢,时刻记住套接字是为了标识互联网中的某一台主机上的某一个进程,因此它就是IP地址 + 端口号。现在你完全可以把套接字当成一个结构体,里面包含了这台主机的IP地址和端口号。(只为了方便理解,实际中可能并不止如此)在介绍套接字前,先来认识一下网络字节序。
2025-03-13 18:59:24
827
1
原创 x86-64算术逻辑指令
对于大多数64位除法来说,被除数常常是64位的值,这个值应被存放在%rax(低64位)中,%rdx的值应该被设为全0(无符号除法)或全符号位(有符号除法)。二元操作第一个是源,第二个既是源又是目的,类似C语言+=运算符,第一个操作数可以是立即数、寄存器、内存位置,第二个操作数可以是寄存器和内存位置。除了leaq,其他算数指令都有大小变种,leaq第一个操作数是一个地址,将这个地址复制到第二个操作数中,实际上该指令并不会引用内存,不会管这个地址处存的什么值,只是单纯将这个地址赋值给第二个操作数。
2025-02-02 22:19:54
518
原创 x86-64数据传输指令
关于汇编语言一些基础概念的更详细的介绍,可移步该指令集中一个字2字节。该架构有16个64位寄存器,名字都以%r开头,每个寄存器的都可单独拿出来使用。如下图当指令以寄存器为目标时,对于生成小于八字节的结果的指令,有两条规则:生成1、2字节的保持高位不变;生成4字节的把高四字节置为0。这些寄存器中最特别的是栈指针%rsp,用来指明运行时栈的结束位置。在过程的实现中,这个寄存器很重要。
2025-02-01 23:20:28
506
原创 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
853
原创 csapp笔记——2.3节整数运算
对于的整数x,y,定义表示将x与y的和截为w位由此推得检测无符号加法是否溢出得方法是判断结果是否比x,y中的任何一个小。无符号数的逆元定义为使得的y,若x为0则y为0,否则,y为。
2025-01-23 21:18:21
514
原创 csapp笔记——2.2节整数表示
这节很有意思的点在于将整数的编码用数学的语言描述,这样从数学角度思考能更好的理解补码的作用,补码的一些好用的性质,也更加严谨。
2025-01-20 19:49:57
941
原创 MIPS指令集(一)基本操作
这种指令格式在某些场景可能不适用,如lw指令需要传入偏移量,5位是不够用的,这时,想要增加位数,但是MIPS的设计是,所有指令的长度都相同,这样,就会采取折中方案:所有指令长度相同,但不同类型指令采用不同指令格式。机器指令分为多个字段,本例第一个和最后一个告诉MIPS计算机要执行加法操作,第二个和第三个表示源操作数寄存器,第四个字段表示存放结果的寄存器,第五个字段没有用到,故置为0。(add immediate),常数操作数出现频率高,像这种带立即数的指令,比从存储器种取值快很多,能耗也较低。
2024-12-17 22:36:04
1351
原创 C++入门篇(5)——类和对象(2)
如果一个类一个成员都没有,那么这个类就是空类。但空类并非什么都没有,编译器会对任何一个类都生成六个默认成员函数。
2024-02-15 12:57:07
583
8
原创 C++入门篇(4)—— 类与对象(1)
class className //指定想要的类的名字// 类体:由成员函数和成员变量组成// 一定要注意后面的分号这 就是类的定义方式。类体中内容称为类的成员:类中的变量称为类的属性或成员变量;类中的函数称为类的方法或者成员函数。类中的函数有两种定义方式1.直接在类中定义函数,但需要注意,这样编译器可能将该函数视为内联函数。2.类中函数声明,在类外定义函数。在类外定义函数需要注意成员函数名前加上类名。int _year;int _month;int _day;
2024-02-10 20:12:33
2673
6
原创 C++入门篇(3)auto关键字、内联函数、nullptr关键字
这种情况下一行中的变量必须是同一个类型,否则会报错。注意:auto使用时必须初始化,因为编译器需要根据初始化的数据类型确定出auto的实际类型。
2024-02-06 12:31:15
996
7
原创 C++入门篇(1)命名空间、输入输出函数、缺省参数
若有函数声明,则缺省参数只能出现在函数声明中,不能出现在函数定义中。必须像这样,不能声明定义都出现缺省参数,只能有声明出现缺省参数。
2024-02-02 22:59:12
500
4
原创 控制台简易程序——贪吃蛇
在控制台中实现一个简易的贪吃蛇小程序,蛇体可用●代替,作为边界的墙体用□表示,食物用★表示。最终效果如下同时实现蛇的移动,吃食物的反馈,以及游戏结束条件判断。
2024-01-31 22:14:45
3220
5
原创 结构体基础回顾
结构是⼀些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。这个结构体的类型就是struct stu,要用该结构体声明变量时,要使用struct stu声明。要访问结构体中的成员,需使用'.'操作符或者这么写。
2023-12-04 14:28:53
424
1
原创 C语言内存函数
该函数作用类似于strcpy,函数声明如下从source地址拷贝num个字节的数据到destination地址处,这个函数强大之处在于不限制数据类型,可以是整型,浮点型,也可以是结构体。用法如上。结果是但是这个库函数,在C语言该函数是处理两块内存空间没有重合的情况,也就是说像这种用法尽量避免。但是也许在你的编译器上他是可以正常运行,这个可能是因为你所使用的编译器对其进行了优化。
2023-11-30 22:19:12
61
原创 指针知识点归纳
cpu如果想要访问某一块内存空间,就需要让cpu知道这是哪一块内存空间,由此需要对内存进行编址,将内存划分为一段段的小空间。指针变量就是接收这种地址编号的变量。cpu和内存之间传递数据,可以理解为用“线”来传递。简单理解,32位机器有32根地址总线,每根线表达“电脉冲有无”也就是0,1。因此32位机器上给内存编号,最多有32个bit位,也就是4字节。同理64位机器上编号最多为64字节。所以在32位机器上,指针变量大小为4字节,64位机器上,指针变量大小为8字节。
2023-11-25 16:04:35
134
4
原创 能排序任意数据类型数组的冒泡排序的实现
C语言中有一个库函数qsort,可以实现对任意类型数组进行排序,其函数声明如下其中base是数组首元素地址,num是无符号整型,意为数组元素个数,size是数组元素中每个元素的大小,单位为字节,而最后一个是一个函数指针,指向的函数会告诉计算机比较两元素的方法,比如比较两个结构体的大小,不能直接想1<2那样简单的直接比较,可以根据结构体中的元素进行比较,比如这个结构体,可以比较age得出两个结构体之间的大小关系,也可以比较name字符串得出二者大小关系。
2023-11-24 12:33:39
83
1
原创 C语言统计整型数组中每个元素出现次数
给定一个整型数组,可以先将其排序再用一个两列的二维数组存放每个数以及出现的次数。count数组中确实存放了1以及1出现的次数。
2023-11-23 12:14:55
1303
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人