自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 命名管道和共享内存

本文介绍了命名管道(FIFO)和共享内存两种进程间通信方式。命名管道通过特殊文件让无血缘关系的进程通信,对比普通文件详述了FIFO的特性:不落盘、必须成对使用、内存级缓冲区等,并提供了mkfifo/unlink接口实现代码。共享内存则通过系统调用创建内核空间,映射到不同进程地址空间实现高效通信,详细讲解了shmget/shmat/shmdt/shmctl等接口和实现原理,强调其速度快但需自行维护同步的特点。最后通过代码示例展示了两种通信方式的具体应用,分析了共享内存的结构体属性。

2025-10-22 08:30:07 8376 58

原创 从零实现一个简易进程池:基于匿名管道的任务分发模型

本文深入解析了进程间通信(IPC)的概念与实现方式。文章首先指出进程独立性导致通信困难,需要通过操作系统提供的共享资源实现数据交互。重点介绍了匿名管道通信机制,其本质是让父子进程共享内存级文件资源,通过pipe()系统调用创建单向通道。文章详细分析了管道的4种工作状态、字节流特性及生命周期随进程的特点,并通过一个进程池的完整案例演示了多进程+管道通信的实际应用。案例展示了父进程分发任务、子进程执行任务的模型,特别强调了正确管理文件描述符的重要性,最后提供了完整的代码实现。

2025-09-18 16:07:06 7660 20

原创 如何实现静态库与动态库的制作

这篇博客介绍了 Linux 下静态库(.a)与动态库(.so)的原理与应用。静态库在编译时直接打包进可执行文件,运行不依赖库文件;动态库需在运行时由系统加载,支持共享,节省内存。文中展示了静态库的生成流程(目标文件 → ar 打包)及动态库的制作方法(-fPIC 生成位置无关代码,-shared 输出 .so),并说明了通过环境变量或 ldconfig 让系统找到动态库。最后结合 ELF 文件结构与地址空间,解释了动态库需位置无关代码的原因,并实验对比了两类库在运行时的差异。

2025-09-13 21:05:03 7890 15

原创 深入理解 Linux 磁盘文件存储:inode、扇区与数据块

本文深入探讨了Linux文件系统在磁盘中的存储与管理机制。文章首先介绍了磁盘的基本物理结构和工作原理,包括扇区、磁道、柱面等概念,以及CHS寻址方式。随后详细讲解了磁盘的逻辑抽象方法,将物理磁盘转换为线性扇区数组。重点分析了文件系统的核心组成部分。文章还解释了文件创建、删除、查看和修改时系统的内部操作流程,以及inode与文件名的映射关系。最后对比了软链接和硬链接的区别,指出软硬链接中需要注意的核心事项。通过这篇文章,读者可以全面了解Linux文件系统在磁盘层面的工作原理。

2025-08-19 08:55:35 8023 18

原创 C 语言 FILE * 与操作系统中文件机制详解

本文从文件操作的基本概念出发,深入探讨了文件描述符、缓冲区等底层原理。首先分析了文件由内容和属性组成。通过C语言文件接口与系统调用(open/write/read等)的对比,揭示了高级语言对系统调用的封装本质。重点剖析了文件描述符的分配规则和重定向原理,解释了标准输入/输出/错误流的本质。最后通过缓冲区刷新策略(行缓冲/全缓冲)的差异,说明了fork()后输出行为不同的原因,并阐述了缓冲区存在的必要性。全文通过大量代码示例,从应用层到系统层逐步深入,帮助读者理解文件操作的底层机制。

2025-08-19 08:55:05 7933 18

原创 Linux文件系统详解——内存中打开的文件(缓冲区部分)

摘要:本文探讨了C语言缓冲区对程序输出的影响。当使用C标准库函数(如printf)时,数据会先存入用户缓冲区,而系统调用(如write)则直接写入内核。向显示器输出时采用行缓冲(遇'\n'刷新),向文件输出时采用全缓冲(需手动刷新或缓冲区满)。在fork()后,父子进程共享缓冲区内容,导致全缓冲模式下数据被重复写入。此外,exit()会刷新用户缓冲区,而_exit()则直接退出不刷新。这些机制解释了为何不同输出方式会呈现不同结果,缓冲区的存在是为了提高I/O效率。

2025-08-19 08:46:18 3845 4

原创 Linux文件系统详解——内存中打开的文件(原理部分)

Linux文件系统原理:进程通过文件描述符(fd)管理打开的文件,内核使用struct file结构体描述文件信息。文件描述符本质是数组下标,0/1/2分别对应标准输入、输出和错误。通过实验验证了文件描述符分配规则(从最小可用位置开始)和重定向原理(使用dup2系统调用)。文章还解释了stdout与stderr的区别,以及"Linux下一切皆文件"的设计理念:通过VFS统一管理外设,将设备操作抽象为文件操作。最后通过代码示例展示了重定向的具体实现方式。

2025-08-19 08:43:22 4019 6

原创 Linux文件系统详解——内存中打开的文件(使用部分)

本文探讨了文件操作的本质与实现原理。文章首先指出学生对C语言文件接口的困惑源于缺乏操作系统层面的理解,强调文件=内容+属性的基本概念,并区分内存级和磁盘级文件。通过类比快递管理,说明操作系统对未打开文件的管理机制。详细分析了C语言文件操作函数与系统调用接口的关系,指出所有语言的文件操作最终都封装了系统调用。文章以open、write等系统调用为例,演示如何实现文件创建、写入等功能,并比较了C语言FILE*与系统调用返回的文件描述符fd的区别。最后揭示了文件操作的底层原理。

2025-08-19 08:40:18 4157 5

原创 进程控制->进程替换(Linux)

本文深入探讨了Linux系统中的进程替换机制。通过exec系列函数,子进程可以完全替换当前进程的用户空间代码和数据,转而执行新的程序。文章详细介绍了execl、execlp、execv、execvp等函数的用法和区别,并通过代码示例展示了如何替换系统命令、自定义程序以及跨语言脚本。解释了进程替换的原理,包括写时拷贝技术如何保证进程独立性。特别说明了execle和execve函数如何传递环境变量,以及如何自定义环境变量。文章指出,虽然exec系列函数有多个变体,但最终都调用execve这个系统调用实现进程替换

2025-07-25 21:35:22 7582

原创 进程控制->进程等待(Linux)

本文详细介绍了进程等待机制。通过具体的代码示例,解释了父进程如何使用wait和waitpid系统调用回收子进程资源,防止产生僵尸进程,从而避免内存泄漏。文章还分析了如何通过status参数获取子进程的退出信息,包括退出码和终止信号,并结合位运算与宏函数WIFEXITED、WEXITSTATUS进行解析。此外,还介绍了非阻塞轮询的实现方法,使父进程可以在等待子进程的同时继续执行自己的任务,提升程序灵活性。通过丰富的示例和类比,帮助读者深入理解进程控制的原理与实践应用。

2025-07-12 08:30:00 4256

原创 进程控制->进程的终止(Linux)

这篇博客讲解了 Linux 系统中进程控制的核心机制,包括虚拟内存的作用、fork 函数实现的进程创建、进程调度的不确定性、写时拷贝(COW)的原理、进程终止的多种情形(正常结束、异常中止),以及退出码的意义和用法。文中通过多个代码示例演示了父子进程的执行流程、如何使用 exit 和 _exit 终止进程,以及缓冲区刷新策略对输出行为的影响。此外,还介绍了 Linux 信号与错误码机制,为后续深入理解进程替换和信号处理打下基础。

2025-07-08 08:00:00 4208

原创 程序地址空间详解(Linux)

在上一篇博客的结尾我们简单介绍了一下程序地址空间,对程序的地址空间分布有了视觉上的感受我们可以看到在栈区是向下增长的,而堆区是向上增长的,因为,我们先定义的变量n1 - n4的地址是逐渐变小的,而在n1 - n4里申请存放的堆区地址是逐渐增大的,所以栈区是向下增长,而堆区是向上增长的。了解了程序地址空间,我们再来看下面这段代码,看看会有什么新奇的事情发生?这段代码的意思就是定义一个全局变量,父子进程同时打印这个全局变量的值和它的地址,子进程在过一段时间后对全局变量的值进行改变,结果会发生什么呢。

2025-06-24 21:24:07 4064

原创 进程的详解,命令行参数,程序的地址空间(Linux)

在上一篇博客结束的时候,我们了解了僵尸进程,现在我们接着僵尸进程继续往下探索,所谓的僵尸进程就是当子进程退出时,父进程如果一直不对子进程进行回收,子进程的状态就会一直变成僵尸状态(Z状态),这就好比你的女朋友给你分享了一个很有意思的视频,希望可以和你得到情绪共鸣。但是你呢,经常打游戏打的什么都顾不上,而在那边你女朋友一直等待你回复一下这个视频好不好看,但是迟迟等不到你的回复。此时,你女朋友的状态就属于僵尸状态,一直等待你的回复。

2025-06-06 19:03:02 4421

原创 STL库容器之一:vector

本文介绍了C++ STL中vector容器的实现原理与关键特性。vector是一种动态数组,使用连续存储空间,支持快速随机访问。与静态数组相比,vector能动态调整大小,其核心实现包含三个指针:_start指向首元素,_finish指向末元素后位置,_end_of_storage指向分配空间末尾。文章详细分析了vector的构造、迭代器、容量管理(resize/reserve)和增删改查操作,重点探讨了迭代器失效问题(由扩容或删除引起)及解决方案。特别指出使用memcpy拷贝资源管理对象会导致浅拷贝问题,

2025-05-29 17:51:19 7414

原创 写时拷贝(Copy-On-Write)

先简单列举一个生活中关于“写时拷贝”的例子,在大家上学的时候,相信大家一定都写过实验报告,每次写实验报告的时候,班级里的学习委员比如就会说,咱们的这个实验报告在这周五下午五点,交到我的手中,我再将实验报告交给老师,爱玩游戏的兄弟们一看,赶紧问一问学习委员这是交什么实验报告呀?学习委员说明情况后,你恍然大悟想到,那天是有一把很重要的游戏晋级赛,所以就没有去那节实验课。

2025-05-24 17:15:17 4055

原创 进程的详细讲解(Linux)

task_struct是Linux描述进程的结构体task_struc是linux内核的一种数据结构,它被装载到内存(RNA)里并包含着进程的信息。task_struct的内容分类标识符:描述进程的唯一标识符,用来区别其他进程。状态:任务状态,退出状态,退出信号等等。优先级:相对于其他进程的优先级。程序计数器(PC):程序中将要被执行的下一条指令的地址。内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享内存块的指针。上下文数据:进程执行时处理器中寄存器的数据。

2025-05-18 12:17:49 7578

原创 STL库容器之一:string(深浅拷贝以及VS和G++的扩容机制)

STL(标准模板库)中的string容器是C++中用于处理字符串的类,提供了丰富的功能来替代C风格的字符数组,具有更高的安全性和便捷性。以下是对string:需包含<string>。:是的别名,管理动态字符数组,自动处理内存(无需手动分配/释放)。:支持动态扩容、丰富的成员函数、操作符重载,避免缓冲区溢出。接下来是string的一些接口函数,我们挑几个函数进行实现,达到让我们自己写的string可以使用一些基本功能即可。string类对象的成员变量。

2025-05-04 14:50:38 4040

原创 模板和STL库的简单介绍

class 类模板名//类的实现// 动态顺序表public:, _size(0){}// 使用析构函数演示:在类中声明,在类外定义。~Vector();// 注意:类模板中函数放在类外进行定义时,需要加模板参数列表if (_data)注意:类模板的实例化需要在类模板名字后跟<>,将实例化的类型放在<>内即可,类的名字不是真正的类,实例化后的结果才是真正的类。其中vector是类名,vector<int>是类型。

2025-05-03 11:20:54 4216

原创 数据结构-AVL树(图解+全面分析平衡二叉树)

K _key;int _bf;,_key(key),_bf(0){}之所以使用三叉链结构,是因为AVL树的核心是通过平衡因子(BF)调整树的平衡性。当插入或删除节点时,需要沿着路径向上回溯到根节点,逐层更新祖先节点的平衡因子。通过_parent指针可以直接访问父节点,代码更简洁高效AVL树的旋转(左旋、右旋、双旋)需要调整父子节点的指向关系,涉及多个节点的指针修改。通过_parent指针,可以直接修改父节点对子节点的引用,无需从根节点重新定位父节点,减少指针操作的复杂度。

2025-04-09 16:35:40 7517

原创 让我们看看C++类中的默认成员函数到底是什么?(外加常量指针和指向常量指针的区别)

默认成员函数:就是即使类内什么都不写(就像之前我们在类对象的大小那里说的空类),编译器也会自动生成6个默认的成员函数,这6个成员函数称为默认成员函数。

2025-03-31 10:09:11 3914

原创 猜一猜C++类中的对象模型是什么样的?

class Date//由成员函数与成员变量组成class为定义类的关键字,Date为类的名字,{}中是类的主题,同时注意类的定义结束后面的分号不能省略。这样一看会不会觉得类的定义与C语言中的结构体的定义有异曲同工之妙呢?//类型的定义这是因为C++需要兼容C语言,所以C++中的struct既可以当成结构体使用,同时还可以用来定义类。和class定义的类是一样的,两者的区别在于struct定义的类默认访问权限是public,class定义的类默认访问权限是private。

2025-03-31 10:06:28 4062

原创 C++基本知识以及重载的原理和引用(详解)

不论采取何种定义,在使用空值的指针时,都不可避免的会遇到一些麻烦:程序本意是想通过f(NULL)调用指针版本的f(int*)函数,但是由于NULL被定义成0,因此与程序的初衷相悖。在C++98中,字面常量0既可以是一个整形数字,也可以是无类型的指针(void*)常量,但是编译器默认情况下将其看成是一个整形常量,如果要将其按照指针方式来使用,必须对其进行强转(void*)0。所以nullptr是C++11作为新关键字引入的。

2025-03-25 15:00:00 8254

原创 函数栈帧的创建与销毁

函数的栈帧(Stack Frame)是程序执行过程中,用于存储函数调用相关信息的一块内存区域。每当一个函数被调用时,系统会在调用栈(Call Stack)上为其分配一个栈帧,用于保存该函数的局部变量、参数、返回地址等信息。栈帧在函数调用结束后会被释放。

2025-03-21 15:25:54 7515

原创 数据在内存中的存储

大端存储方式:数据的低位在内存中的高地址处存储,数据的高位在内存中的低地址处存储。小端存储方式:数据的高位在内存中的高地址处存储,数据的低位在内存中的低地址处存储。下面解释一下为什么存在大小端字节序:多字节数据类型的存储方式:整数和浮点数通常由多个字节组成,例如4字节整数或8字节浮点数。这些字节需要以某种方式存储在计算机的内存中。问题在于,这些字节应该按照什么顺序存储,高位字节(most significant byte)在前还是低位字节(least significant byte)在前。

2023-10-22 17:58:04 203 1

原创 简单扫雷(9X9)—从零开始

简单的扫雷游戏

2023-10-17 09:00:00 253

原创 井字棋游戏

这个C语言实现的井字棋游戏是一个非常基础的示例。通过这个项目,我深入了解到了C语言的核心概念,如函数、条件语句和循环。不仅如此,我还可以通过这个项目了解如何管理用户输入和处理游戏规则。无论如何,这个项目为我学习和练习C语言编程提供了一个出色的起点。希望这篇博客对你了解如何使用C语言构建一个井字棋游戏有所帮助,以及为你的编程学习提供了一个有趣的项目方向。

2023-10-15 18:43:26 188 1

空空如也

空空如也

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

TA关注的人

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