自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 进程与线程

close会将描述符的引用计数减一,如果引用计数变为0,就关闭描述符,发送FIN。多路IO复用:对于处于闲置状态或者处于IO阻塞的状态,把阻塞的socket放置一边,来避免等待所带来的资源耗费,即非阻塞IO的概念。进程的pid使用pid_t表示的,为short类型变量(2字节),因此可以支持32768(2^15)个进程。因此进程最多可以创建的线程数是根据分配给调用栈的大小,以及操作西戎(32未,64位)共同决定的。协程是线程内部调度的基本点位,线程是程序执行的最小单位,进程是操作系统分配资源的最小单位。

2024-09-03 14:49:03 870

原创 STL相关知识点

主要介绍STL中容器的相关知识点

2024-09-03 11:06:17 817

原创 Muduo04 配置项目的CMake文件

关键字指定要创建的是一个共享库(而非静态库)。最终生成的库文件会被输出到之前指定的。是一个 CMake 内置变量,表示 CMakeLists.txt 文件所在的目录,这行代码设置了运行此 CMake 配置文件所需的最低 CMake 版本。是一个 CMake 命令,用于将指定目录中的所有源文件(如。因此,这行代码指定所有生成的库文件(如。这行代码设置了生成的动态库(共享库)的输出路径。)中的所有源文件,并将它们添加到变量。文件)都会被放置在项目根目录下的。中的所有源文件编译成一个名为。的共享库(动态库)。

2024-09-02 20:04:35 344

原创 Mudo03 vscode配置相应的文件的搜索路径,库文件的搜索路径以及想要的链接库

是 Visual Studio Code 的任务配置文件,用于定义和配置各种任务(Task)。使用muduo库,需要链接libmuduo_base.so、libmuduo_net.so 、libpthread.so。:指定项目的编译器路径,头文件搜索轮径,编译选项等信息,以便编译器能够提供准确的代码补全,语法检查和调试功能而。:定义调试配置,包括要调试的程序,启动参数,调试器类型,断点设置。VScode上如何配置相应的头文件的搜索路径?-I:头文件搜索路径。-L:库文件搜索路径。

2024-09-02 19:55:54 461

原创 Muduo 02 select poll epoll比较

epoll使用双向链表:主要用于事件的通知和分发。当某个文件描述符上发生了一个事件,这个描述符会被加入到一个双向链表中,当调用epoll_wait函数时,会检查这个双向链表返回那些已经准备好的文件描述符。水平触发机制:事件没有处理完成时,每次调用select都需要通知进程。采用链表的方式村存储文件描述符,其他的跟selcet一样的。使用内存映射,不需要从用户空间频繁拷贝fd数据到内核空间。开销大:每次都需要把描述符从用户空间拷贝到内核空间。epoll使用红黑树来管理和存储注册的文件描述符。

2024-09-02 19:39:38 270

原创 Muduo 01 知识储备

阻塞与非阻塞:对一个线程来说,阻塞表现形式就是当前线程会阻塞到这个线程的运行的数据准备好,非阻塞的方式就是立刻返回,会通过返回值进行判断。异步非阻塞IO:用户进程进行aio_read系统调用之后,无论内核数据是否准备好,都会直接返回给用户进程,然后用户态进程可以去做别的事情。进程在返回之后,可以执行其他任务,然后再发起recvform系统调用,重复上面的过程,循环往复的进行recvform系统调用(轮询)异步:当客户端发送给服务端请求时,在等待服务端响应的时候,客户端可以做其他的事情,这样节约了时间。

2024-09-02 16:34:48 979

原创 磁盘与Fat16系统

只使用LBA模式对磁盘进行读写,而不是难于理解地的CHS模式。在LBA操作模式下,磁盘就是一块块连续的、相同大小的扇区集合。FAT16文件系统的结构以及工作原理,同时还在整个文件系统中增加了该类型文件系统相关的接口支持。FAT16文件系统采用的是不连续的存储方式:将文件拆分成多个相同的数据块,然后在磁盘分区中找到空闲簇,写入簇。FAT16为了便于快速找到文件中簇链的链接关系,将这种关系单独放置到了FAT表中。每一个表项都对应于一个簇,表项的值代表了簇的下一簇是什么。

2024-09-02 14:51:08 864

原创 使用文件系统管理硬件设备

对sys_open代码进行了优化,使得其打开方式做到更加通用,不再直接使用devfs_open,而是根据路径找到对应的文件系统fs_t结构,再调用其中的open函数,进而使得其代码变得更加通用。对sys_read/sys_write等函数实现做了修改,使其全部采用调用文件系统fs_t中相应的回调函数来完成文件的特定操作,而无需再像以前那样调用设备管理层dev_xxx中的接口。我们设计了 fs_t结构用于描述某种特定的文件系统。注意的事项为:在打开设备文件系统中的文件时,默认文件名最后的几位为次设备号。

2024-09-01 16:50:30 1240

原创 实现一个命令行解释器

由于getopt将会在其它命令的执行时重复使用,因此需要在退出echo命令的执行时,将optind重置。在应用程序的执行过程中,程序可能会主动结束执行,或者从main返回,因此需要给进程一个主动退出执行的接口。使用echo命令时,使用的形式为echo -n 重复数量 -h 待重复的字符串,其中有-n和-h为选项,且-n的后边必须加上一个数量值。当返回时-1时,表示已经没有参数,即对于echo -n 重复数量 -h 字符串,表示已经扫描完所有以-开头的选项,后续已经没有其它选项。,包含可以被执行的若干指令。

2024-09-01 15:39:46 704

原创 设备管理与文件系统

文件系统的常见功能是将磁盘上的数据抽像成文件和目录,并将其组织成目录树的形式,一切皆文件(设备,外设接口)6、为进程添加文件打开表每个应用程序在运行过程中,都有可能打开文件并进行读写,且各个应用程序之间操作文件行为应当相互不干扰,以及多个进程同时打开同一文件中要处理冲突的问题解决办法:定义一个全局的file_t文件表,其中包含所有打开的文件表。每个进程只维护一个指针,指向表中的某个文件。每个进程既有自己的打开文件表,同时也能够方便实现文件地共享、处理打开同一文件的冲突问题。

2024-08-31 17:27:59 955

原创 使用控制台与键盘进行输入输出

计算机在上电启动后,显示器被默认配置成80x25列的文本显示模式。其使用从0xb8000开始,一共32KB的显存用于显示。如要在屏幕上指定位置显示特定的字符,则只需找到该位置对应的显存地址,写入2字节的数据:ascii码和颜色属性字节。由于一屏共8025个字符,每个字符占用2个字节,所以一屏字符显示需要约4000字节数据。而显存一共32KB,因此这些存储区域可以存储8块屏幕的显示数据。后续可以通过切换对应的显存屏幕数据。

2024-08-31 16:27:47 1064

原创 使用C标准库中的printf输出

在newlib库中,当我们使用malloc进行内存分配时,就会从堆中分配一大块内存,然后再自行对这块内存进行管理,从中分配要求的大小的内容。printf中的参数会被格式化成最终的字符串,该字符串会被传入系统调用write作为参数,而现在我们只能将字符串打印到串口,暂时还没有写到屏幕上的方法,因此在实现中,直接使用了log_printf打印。级I/O和文件系统访问(open、close、read、write、lseek、stat、fstat、fcntl、link、unlink、rename);

2024-08-31 15:25:14 510

原创 新进程的加载与创建

首先,需要为系统调用预留接口并添加相应的ID,然后在库函数中实现该系统调用的接口。接着,需要处理系统调用的映射表,调用task.c中的函数实现进程主动放弃CPU的功能。当fork()返回值会返回进程的id,当进程发现pid==0,就知道了自己是fork出来的子进程;创建完成就是增加exec()系统调用,与实现fork()系统调用过程一样,其功能就是使用sys_exec加载应用程序。1)建立独立的 不和操作系统代码文件一起编译的文件,比如建立main.c文件,添加main函数。fork创建子进程。

2024-08-31 15:03:20 494

原创 建立系统调用

然后在执行系统调用时,从传入的参数中获得需要调用的函数对应的id。为了取得系统调用传入的函数,课程定义了syscall_frame_t结构来解析栈中的寄存器和参数值,通过该结构体,即可获得系统调用传入的参数,以及当前执行系统调用时的状态。根据GCC对函数返回值的处理规则:函数调用的返回值保存在eax寄存器中,在系统调用之后,执行frame->eax=ret,用于将执行结果返回给应用程序。使用向量号为0x80的中断门,当需要执行系统调用时,执行int 0x80指令,参数也是通过寄存器传递。

2024-08-30 15:20:14 286

原创 隔离操作系统与进程

这些区域的分布,可以通过链接脚本来配置,通过kernel.lds中的配置,可以控制这些代码和数据在内存中应该存在的位置。在kernel.elf被加载到内存中后,first_task中的所有的代码和数据还只存在于1MB以下的内存中。init_main运行在权限级0的模式下,而first_task需要运行在特权级3,因此这里涉及到从高特权级切换到低特权级的情况。,但是由于没有文件系统,二者仍然是一同编译的,所以最终汇编出来的文件中,first_task和内核的代码是混在一起的。:1位,控制页面的可写权限。

2024-08-29 15:41:15 805

原创 虚拟内存管理和保护模式

启动分页机制后,应用程序就看不到机器的物理内存了,看到的就是虚拟的,不存在的内存空间。这块虚拟内存也是划分成了一个个4KB的内存页。操作系统会通过·页表将这些虚拟内存空间中连续的内存页,从物理内存空间中找空闲的物理页,简历一个映射关系。就可以将多个不连续的物理页,变成了进程使用的连续内存页。这样进程就感觉自己在使用连续的内存页,而实际最终在物理内存的表现上却是实现不连续的内存页。页表由CR3来管理。

2024-08-29 14:16:00 712

原创 进程间的同步与互斥

1)等待信号:对于等信号量而言,如果事件或资源的计数不为0,则说明事件已经发生或者资源是可用的,所以不需要等,而如果为0,则需要等待,进程不能继续往下运行。2)发送信号:当事件发生或者资源可用时,如果有进程在队列中等,则唤醒一个进程让其可以继续往下运行。由于事件发生的次数可能不止一次,或者资源可用的数量可能不止一个,因此,信号量内部会维护一个计数器,用于表示某种事件发生的次数或者某种资源可用的数量。等待队列的排序顺序设置比较简单,当事件发生或资源可用时,最先等待的进程最先获得事件的处理权。

2024-08-29 10:15:51 325

原创 任务管理与延时

由于系统中可能会有多个进程同时延时,为了将这些进程有效的管理,额外做了一个延时队列,将需要延时的进程暂时插入到就绪队列中。目前的系统中,CPU总是被用于安排运行处于就绪队列头部的进程的代码,所以导致了如果该进程总是处于头部,那么其后的任务将迟迟得不到运行的机会,会被活活“饿死”当系统中所有任务都尝试延时时,系统将崩溃,操作系统不知道做什么,因此考虑增加空闲进程,这个进程就是在其他进程都不需要运行的时候才运行。使用sys_sleep进行延时,实际的延时是有误差的,不会准确的延时指定的时间。

2024-08-29 09:54:49 300

原创 实现链表数据结构

既要将结点的前后结点中相应的指针重新进行设置,将前一结点的next指向后面的结点,将后一结点的pre指向前面的结点。此外,如果结点位于链表的头部或者尾部,还需要更新first或last指针。所实现的链表为双向链表,既每个结点中包含两个指针: next指向后继结构,pre指向前驱结点。1)删除头部要考虑到队列只有一个结点的情况,因为这意味着在修改first指针时还要同时更新last指针,将last设置为空。插入尾部也要特别考虑队列为空的情况,因为如果为空,则还需要更新first指针。

2024-08-28 11:10:04 168

原创 实现简单的进程切换

在执行该指令时,CPU会自动将保存当前任务的状态到TSS,然后从另一任务的TSS中取出状态进行恢复。进行不同程序运行的切换时,需要将前一个程序完整的运行状态全部保存到TSS,这样当后续该程序需要再次运行时,再将该状态进行从TSS中恢复,从而就像能完整地继续从上次切换的位置继续往下运行,好像什么都没发生一样。目前只需要在切换时,保存号当前的段寄存器、通用寄存器、EIP、EFLAGS中的内容到当前程序的TSS中,然后再加载下一个将要运行程序的TSS中段寄存器、通用寄存器、EIP、EFLAGS值进行恢复。

2024-08-28 10:42:25 510

原创 日志与printf格式化输出

当有更多参数时,如func_arg(a, b, c, d, e),则栈中压入的参数从上(高地址)到下(低地址)依次为e, d, c, b , a。在函数内部,只有func_arg(int a, ....)中的a参数有名字可以引用,而要获取其它参数,则需要借助a找到对应的栈位置,然后再在栈中依次往上(高地址)逐个去取出相应的参数。课程使用RS232接口进行输出,其通过两根信号线:发送信号、接收信号,便能实现与外部的数据输入输出通信,qemu有实现对这种接口的模拟。不过,不同的显示终端对于\n的解释不同。

2024-08-28 10:03:02 473

原创 中断系统配置

分段(Segmentation):将内存划分为若干段,每个段都有起始地址和长度,并用来提供不同的内存视图,如代码段、数据段和堆栈段等。分页(Paging):将内存划分为固定大小的页(通常是 4KB),并使用页表将虚拟地址映射到物理地址,以支持虚拟内存管理和地址空间隔离。即段式存储与页式存储。

2024-08-28 09:34:11 1226

原创 加载:loader实现

内联汇编显示字符串:利用显示单个字符的原理检测内容容量:利用BIOS的软中断服务切换到保护模式:A20地址线的开启,使得可用内存不局限于1MB,采用GDT表管理内存,使用LGDT寄存器指明GDT表的基这地址和大小进入保护模式,不方便用BIOS的软中断,因此引入LBA进行磁盘读取,在加载内核文件时,需要对ELF文件解析,将内核相关数据、代码保存到内存的指定位置,然后跳到指定地址去执行内核代码。

2024-08-27 14:54:55 723

原创 引导:boot实现

boot和loader下都有对应的汇编文件。了解计算机启动流程?启动—跳转到BIOS—自检—加载引导代码—引导代码加载操作系统到内核—跳转到操作系统执行BIOS自检完成会检查第0扇区最后两个字节是够是x55, 0xaa,来确认是否包含有效的引导代码。

2024-08-27 11:00:58 1419

原创 开发环境准备

如前面所述,不要在Ubuntu中的snap工具中安装VSCode,请从微软官网下载安装VSCode。主要原因是snap封装了一个环境。缺省情况下,GCC工具链可通过如下位置点击后选择,但随着VSCode版本升级,其界面也有所变化,所以下面的工具条不一定可见。,点击下载deb包。下载完成后,使用如下命令安装或者双击安装。vscode默认不允许在汇编中设置断点,所以我们需要修改其缺省配置。

2024-08-27 09:44:20 227

原创 int main(int argc, const char *argv[ ]) 介绍

int main(int argc, const char *argv[]) 是C和C++程序的主函数定义,包含两个参数,用于接收命令行参数 int main: main是程序的入口点。每个C或C++程序都从main函数开始执行。 int表示main函数返回一个整数值。返回值通常表示程序的退出状态,其中0表示成功,非0值表示错误。 int argc: argc是一个整数参数,表示传递给程序的命令行参数的数量。 argc的值至少为1

2024-05-20 16:42:55 425

原创 IIC通信详细介绍

IIC通信协议介绍

2024-05-10 12:34:12 1206

原创 ARM指令学习笔记

汇编、ARM指令、栈、ATPCS协议

2024-05-08 17:16:22 638 1

原创 ARM处理器介绍

ARM相关介绍

2024-05-07 20:36:17 779

原创 进程和线程通信学习笔记

进程、线程、线程和进程间通信

2024-05-07 14:51:59 760

原创 文件IO学习笔记

文件IO学习笔记:标准文件IO、文件、目录、库等介绍

2024-05-06 15:07:07 791

原创 C语言学习笔记1

在递归函数中,通常会使用非静态局部对象(栈对象)来存储递归调用中的临时变量和中间状态。Return关键字的作用是返回流程的控制权,只要使用了return,不管有无返回值,都表示该函数调用结束。指针变量进行相减是指针所代表的地址进行相减,将得出的值除以指针所指向的空间所占据的字节数。野指针:就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)指针类型决定了对指针解引用的时候有多大的权限(能操作几个字节)->是成员选择(指针):对象的指针指向成员名。指针指向的空间释放(即使已经置NULL)

2024-04-28 22:07:11 242

原创 mysql学习笔记4

如果已经跟上master的写入二进制文件的速度,就会睡眠等待master产生新的事件,然后这个从服务器的IO线程把读取的事件写入到中继日志中。)二进制日志(BInLOG):记录了所有的DDL(数据定义语句)和DML(数据操纵语句),不包括数据查询语句。是在事务开始后,就开始记录,不管事务是否提交都会记录下来,在异常发生时,innoDB会使用redolog恢复到掉电前的时刻,从而保证数据的完整性。从线程从中继日志中读取事件,并重放其中的事件而更新slave服务器的数据,使得其与master的数据一致。

2024-04-25 22:58:16 953 1

原创 MySQL学习笔记3

因为每一次select都会产生一次数据快照,其他事务增加了和当前事物查询条件相同的新的数据并且已经被成功提交,导致当前事务再次以同样的条件查询时,数据多了。因为第一次产生数据快照,其他事务虽然修改了最新的数据,但是当前事务被select时,依然查看的是最初的快照数据。语句的执行,要么全部成功,要么全部失败,不能出现部分成功,部分失败的结果。:事务B读取了事务A新增加的数据或者读不到事务A删除的数据(数据已提交、可重复读):事务B读取了事务A已经提交的数据,查询两次结果不一样(数据已提交、不可重复读)

2024-04-24 22:00:14 434

原创 MySQL学习笔记2

如果原来的索引存在数据类型转换,则不能用索引了,这个转换的字段用到mysql的函数也无法用到索引了。多列索引:在表的多个字段上创建索引(uid+cid 多列索引必须使用到第一个列,才呢呢个用到多列索引,否则索引用不上)是建立在数据库表中的某些列上的。因此在创建索引的时候,应该考虑在那些列上可以创建索引,那些列上不能创建索引。树由于每个节点都存储关键字和数据,因此离根节点进的数据,查询的就快,离根节点远的数据,查询的就慢;给字符串列创建索引的时候,不管这个索引列字符串的长度有多长,也不好。

2024-04-23 23:08:42 539

原创 MYSQL学习笔记1

比如选课关系表为SelectCourse(学号, 姓名, 年龄, 课程名称, 成绩, 学分),(学号,课程名称)是联合主键,但是学分字段只和课程名称有关,和学号无关,相当于只依赖联合主键的其中一个字段,不符合第二范式。特点:减少数据冗余(主要好处,其他好处由此附带的),消除异常(插入异常、更新异常、删除异常),让数据组织的更加和谐。Enum和set :都是限制该字段只能取固定的值,但是枚举字段只能取一个唯一的值,而集合字段可以取任意个值。一个库对应一个文件夹,一个文件夹对应表的结构,表的存储。

2024-04-23 01:11:40 466

原创 C++中 &*的用法

与* 连续出现时,它们相互抵消对方的作用,但是在此过程中,编译器会强制类型转换,将迭代器或者指针转换为指向同一对象的普通指针。这种转换的结果是得到一个与原始指针具有相同指向的指针,但是其类型可能不同。C++中&*的用法,通常用于将一个迭代器或指针转换为一个迭代器或者指针转换为一个指向相同对象的指针。当你有一个指针或者迭代器时,但是需要传递一个普通指针给函数或者存储在一个普通指针中时。

2024-04-20 20:57:08 173

原创 Pytest+Allure+Request+Yaml

pytest+allure+request+yaml

2024-04-19 13:57:59 758

原创 pytest 进阶

pytets入门到精通

2024-04-16 11:14:53 810

pytest+request+allure+yaml 测试框架源码

pytest测试源码框架包 1、这些都是关于pytest、request、yaml等测试框架 2、新入手的伙伴可以根据源码学习,学习效率更高 3、里面代码看不懂,可以问AI工具,每行代码都有详细介绍,很方便,上手也快

2024-04-19

空空如也

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

TA关注的人

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