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

原创 线程的同步和互斥

本文通过售票系统案例剖析多线程并发安全问题及其解决方案。当多个线程同时访问共享变量ticket时,由于判断、输出和自减操作的非原子性,会出现超卖和数据不一致问题。核心原因在于ticket--等操作在底层需要多个步骤完成,线程切换可能导致中间状态被覆盖。解决方案是引入互斥锁机制,通过硬件(如关中断)或软件(标志位检查)方式实现原子操作。关键原则是所有线程必须遵守相同的加锁/解锁协议,才能有效保护临界资源。文章揭示了多线程编程中同步机制的必要性及其实现原理。

2026-07-09 09:57:48 189

原创 线程的控制

本文深入探讨了线程的核心概念、性能优势、应用场景及编程注意事项。线程作为轻量级进程,共享进程资源但拥有独立的执行上下文,其切换速度优于进程,主要得益于虚拟地址空间不变和CPU缓存的高命中率。线程适用于IO密集型任务(如文件读写、网络请求)和计算密集型任务(需多核并行),但也面临健壮性降低、编程复杂度提升等挑战。文章还详细解析了pthread_create函数的参数传递机制,强调了类型安全转换的重要性,并提供了C和C++的代码示例。理解线程的关键在于把握其共享与隔离的平衡,合理规避并发风险。

2026-07-06 16:04:49 324

原创 _线程基础

Linux线程与进程的核心机制 线程与进程的本质区分: 进程是资源分配的基本单位,包含代码、数据等资源 线程是执行调度的基本单位,共享进程资源但拥有独立执行上下文 Linux线程实现: 采用轻量级进程(LWP)模型,复用进程的内核结构task_struct,使线程成为共享地址空间的"缩小版进程" 内存管理机制: 物理内存按4KB页框管理,通过struct page数组组织 虚拟地址通过多级页表映射物理内存(10+10+12位划分) MMU硬件自动完成地址转换,支持懒加载和写时拷贝 线程库实现: pthrea

2026-06-29 19:08:14 339

原创 信号的中断

计算机系统核心机制解析 本文摘要聚焦计算机系统的三大核心机制:CPU中断处理、进程调度和系统调用。 中断处理机制:CPU通过中断控制器响应外设请求,保存当前上下文后查询中断向量表执行处理程序,完成后恢复现场继续原任务。硬件中断是操作系统管理外设的关键机制。 进程调度原理:操作系统通过时钟中断强制获取控制权,利用时间片轮转实现多任务并发。当进程时间片(task_struct中的counter)耗尽时,调度器选择新进程执行上下文切换。 系统调用实现:用户程序通过软中断(如int 0x80)主动陷入内核,CPU从

2026-06-17 20:00:32 243

原创 信号的保存

Linux信号机制通过三张核心表(Block、Pending、Handler)管理信号。信号产生后可能因阻塞而进入Pending状态,待条件允许时才会递达。Block表决定哪些信号被屏蔽,Pending表记录未处理的信号,Handler表定义信号处理方式。通过sigprocmask等函数可操作这些表,实现信号的精确控制。实验表明,信号处理函数执行时,Pending表中对应信号位已被清除,说明内核是在调用Handler前完成Pending状态的更新。

2026-06-11 13:52:43 305

原创 ___信号

摘要: 本文从生活实例引入Linux信号概念,解释信号作为异步事件通知机制的本质和作用。信号处理包括默认、忽略和自定义三种方式,生命周期涵盖产生、保存和处理三个阶段。通过signal()函数可重定义信号行为(如拦截Ctrl+C)。重点剖析程序崩溃原理:硬件检测异常(除零/野指针)触发OS向进程发送信号(SIGFPE/SIGSEGV),本质是修改进程PCB中的信号位图,最终导致进程终止。文章强调信号与信号量的本质区别,并提供核心API的代码示例和信号处理流程图解。(149字) 关键词: Linux信号、异步通

2026-06-07 21:11:57 406

原创 System V共享内存

共享内存知识点

2026-06-02 14:49:48 225

原创 C++多态

本文介绍了C++中的多态机制,重点分析了动态多态的实现原理。主要内容包括: 多态分为编译时多态(函数重载、模板)和运行时多态(虚函数机制) 动态多态的实现条件:必须通过基类指针/引用调用虚函数,且完成虚函数重写 虚函数重写要求:派生类虚函数与基类虚函数的返回值类型、函数名、参数列表完全相同 通过售票示例代码演示了多态的实际应用 深入分析了一个典型问题:虚函数默认参数的静态绑定特性与函数体的动态绑定特性如何共同作用,导致输出"B->1"的结果 重要结论:不要重新定义继承而来的虚函数的默认参数值 文章揭示了C+

2026-05-29 11:20:58 223

原创 c++继承

本文介绍了C++继承机制的核心概念与应用。主要内容包括: 继承的核心作用:实现代码复用和抽象共同基类,子类可扩展并支持多态。 三种继承方式及权限变化: public继承保持原权限 protected继承将public降级为protected private继承将所有可见成员变为private 基类private成员始终不可见 继承中的特殊转换规则: 派生类对象可赋值给基类指针/引用(无需const) 派生类对象可切片赋值给基类对象 作用域规则: 派生类同名成员会隐藏基类成员 可通过基类::成员显式访问 函数

2026-05-28 21:05:34 227

原创 C++模板进阶

本文介绍了C++模板的使用方法,包括函数模板和类模板。主要内容有: 函数模板分为只含类型参数和同时包含类型参数与非类型参数两种形式 类模板同样支持类型参数和非类型参数,非类型参数常用于指定固定容量 模板特化的概念和应用场景,包括函数模板特化和类模板特化 类模板特化分为全特化(参数完全确定)和偏特化(部分参数特化或参数类型限制) 函数模板特化的实现方法和注意事项 文章通过代码示例详细展示了各种模板的使用方式,并比较了特化与普通函数的区别,为C++模板编程提供了实用指导。

2026-05-28 17:19:43 347

原创 c++模板初阶

本文介绍了C++中的模板机制,重点讲解了函数模板和类模板的使用方法。函数模板通过typename/class关键字定义通用函数,编译器根据调用时的参数类型自动实例化具体函数。文章详细说明了模板实例化过程、显式实例化方法以及模板参数匹配原则,指出模板函数与非模板函数共存时的调用优先级。类模板部分展示了如何定义模板类,并强调模板类声明和定义不宜分离到不同文件。全文通过代码示例演示了模板的实际应用,包括类型推导、显式指定类型等常见场景,为理解C++模板编程提供了实用指导。

2026-05-27 22:01:25 42

原创 C/C++内存管理

本文对比了C/C++中的动态内存管理方式。C语言使用malloc/calloc/realloc进行内存分配,其中malloc不初始化内存,calloc会初始化为0,realloc用于调整内存大小。C++则通过new/delete操作符实现,new会自动调用构造函数,delete会调用析构函数。关键区别在于:C方式不涉及对象构造/析构,而C++方式会完整管理对象生命周期。文中通过代码示例演示了malloc/free与new/delete的实际差异,特别展示了后者如何自动处理构造和析构过程。内存管理时需注意配对

2026-05-27 21:34:20 237

原创 再探类和对象

本文介绍了C++中构造函数初始化列表、类型转换、static成员和友元机制等核心概念。主要内容包括: 构造函数初始化列表的语法规则和注意事项,强调三类必须使用初始化列表的成员变量(引用、const、无默认构造函数的类类型)。 类型转换机制,说明隐式类型转换的条件和explicit关键字的作用。 static成员的用法,包括静态成员变量的共享特性和初始化要求,以及静态成员函数的特点和访问限制。 友元机制的特点和使用场景,通过示例展示了友元函数和友元类的声明方式及其访问权限。 这些特性在C++编程中具有重要作用

2026-05-27 20:46:43 382

原创 C++知识点:类和对象

这篇文章详细介绍了C++中的6个默认成员函数,包括构造函数、析构函数和拷贝构造函数。主要内容包括: 构造函数:用于对象初始化,特点包括与类同名、无返回值、可重载等。编译器会自动生成默认构造函数,但用户定义后不再生成。 析构函数:用于对象销毁时的资源清理,特点包括类名前加~、无参数无返回值。编译器会自动生成默认析构函数,但对于需要释放资源的类必须自定义析构函数。 拷贝构造函数:用于对象拷贝的特殊构造函数,第一个参数必须是类类型的引用。编译器会生成默认拷贝构造函数,但对于包含指针成员的类需要自定义深拷贝实现。

2026-05-27 14:59:45 420

原创 C++知识点

本文介绍了C++中几个核心概念:命名空间的三种使用方式(指定访问、using声明和using指令);缺省参数的设置规则(必须从右向左连续设置);函数重载的条件(参数列表不同,与返回值无关);const引用的权限规则(可缩小不可放大权限);内联函数的特性(减少调用开销,建议性展开);类和对象的内存对齐规则(按成员对齐数分配);以及this指针的原理(隐式传递当前对象地址)。这些概念涵盖了C++基础语法和面向对象编程的关键机制,对理解C++程序结构具有重要意义。

2026-05-26 21:40:24 338

原创 进程间通信

本文系统性地介绍了进程间通信(IPC)的核心概念与实现方式。首先阐述了进程通信的四大目的:数据传输、资源共享、事件通知和进程控制。随后详细解析了三种主流IPC机制:管道(匿名/命名)、System V IPC(消息队列/共享内存/信号量)和POSIX IPC。重点剖析了匿名管道的实现原理,通过内核级缓冲区和独立句柄机制实现单向通信,并深入讲解了其五大特性:单向性、血缘限制、字节流传输、随进程生命周期和内置同步互斥。文章还通过代码示例演示了父子进程通过管道通信的具体实现,并分析了四种典型读写场景下的阻塞行为。

2026-05-26 09:43:47 343

原创 ELF动态库

C语言程序启动时,第一个执行的函数并非main()而是_start(),这是通过反汇编分析验证的。程序编译阶段会将外部函数地址暂置为0,链接阶段进行地址修正。静态链接将库代码拷贝到程序中,而动态链接在加载时才解析函数地址。动态库通过共享内存机制实现资源复用,其加载过程涉及虚拟地址分配和缺页中断处理。_start()函数负责初始化堆栈、数据段和动态链接,确保程序正确执行。动态链接的延迟绑定机制提高了资源利用效率。

2026-05-23 10:41:51 392

原创 ELF与库加载

本文总结了Linux下库链接的优先级规则与静态/动态链接机制,详细解析了ELF文件格式及其组成结构(ELF头、程序头表、节头表、节)。通过readelf工具演示了如何查看ELF文件的关键信息,并阐述了程序加载时虚拟地址空间的建立过程。文章还区分了"节"(Section)与"段"(Segment)的概念,指出加载器会将具有相同权限的节合并为段映射到内存。最后解释了编译器采用的平坦编址模式,为理解程序从编译到执行的完整生命周期提供了系统性的技术视角。

2026-05-21 15:24:54 330

原创 库的制作和原理

本文介绍了库文件的本质和使用方法。库文件本质上是.o文件的集合,分为静态库(.a/.lib)和动态库(.so/.dll)。文章详细讲解了如何制作静态库和动态库:使用ar命令打包静态库,使用gcc -shared命令生成动态库。重点说明了库文件的发布方式,包括直接安装到系统目录、使用-I/-L/-l选项链接库文件,以及建立软链接等方法。对于动态库,还特别介绍了运行时查找问题的解决方案,如拷贝到系统目录、建立软链接或设置环境变量等。文章通过具体示例和Makefile脚本,完整展示了从库文件制作到使用的全过程。

2026-05-18 14:42:52 363

原创 文件系统done

本文介绍了Linux系统中的硬链接和软链接概念。硬链接通过创建文件名与inode的映射关系实现文件备份,删除文件时只有当硬链接数为0才会真正删除文件。目录的硬链接数与其子目录数量相关。软链接则是独立的文件,保存目标文件路径,类似于快捷方式,可以简化长路径操作。两者的主要区别在于:硬链接共享inode,软链接有独立inode;硬链接适用于文件备份,软链接用于创建快捷访问路径。文中还通过具体指令演示了两种链接的创建和使用场景。

2026-05-16 21:19:08 203

原创 磁盘与文件系统

本文摘要:文章从操作系统角度探讨了文件系统的底层实现。首先介绍了磁盘的物理结构和工作原理,包括磁道、扇区、柱面等概念,以及CHS和LBA两种寻址方式。然后详细讲解了磁盘数据的管理机制,重点阐述了文件系统如何通过inode结构管理文件属性和内容。文件被分为inode(存储属性)和Data Blocks(存储内容),操作系统通过格式化将磁盘分区并分组管理。文章还解释了扇区与块的关系,以及操作系统为何以块而非扇区为单位进行文件存取。

2026-05-13 21:14:10 400

原创 fd:标准错误

本文介绍了标准错误(stderr)的概念及其与标准输出(stdout)的区别。标准错误用于输出错误信息,默认输出到终端,而标准输出用于正常信息。通过重定向操作符(如2>err.txt)可以将错误信息单独保存到文件。文章还演示了如何使用2>&1将标准错误重定向到标准输出,并通过C++代码示例展示了不同输出方式的效果。最后说明了如何通过重定向分离正常输出和错误信息,便于调试和错误追踪。

2026-05-11 10:35:25 201

原创 缓冲区file

理解语言级缓冲区和内存级缓冲区

2026-05-10 21:30:42 384

原创 理解重定向

对重定向以及io的初步理解

2026-05-06 21:24:29 351

原创 _基础IO

摘要 本文介绍了文件操作的基本概念和实现方式。文件操作涉及对文件内容和属性的读写,需先将文件从磁盘加载到内存。在C语言中,使用fopen()函数打开文件,支持多种模式(如w、a等)。系统调用接口如open()、write()等提供了底层文件操作能力。文件描述符是进程管理打开文件的关键机制,本质是文件描述符表数组的索引。文章详细讲解了文件结构、操作函数、系统调用接口以及文件描述符的工作原理,为理解文件系统提供了基础。

2026-04-29 14:56:01 337

原创 字符串哈希

1.算法原理。

2026-04-06 15:01:24 232

原创 程序替换与shell

程序替换函数

2026-03-31 20:55:02 404

原创 可变参数以及模拟

我们都应该记得,我们最初学c语言的时候,第一个学的代码都是然后老师会介绍说,printf可以打印变量,同时可以打印多个变量哎,那他是怎么实现的呢?这个东西叫做可变参数,主要用到4个东西,这四个都包含在#include <stdarg.h>

2026-03-28 17:14:36 335

原创 进程程序替换

摘要:本文讨论了Linux下多进程编程的实现方法。通过fork()系统调用创建子进程,父子进程执行顺序由调度器决定,通常子进程先退出并由父进程回收资源。文章提供了两种实现方式:串行创建子进程(逐个创建并等待)和并行创建子进程(批量创建后统一回收)。代码示例展示了如何使用vector记录子进程PID,并通过函数指针实现子进程执行不同任务的功能。最后介绍了将代码模块化封装为createchild()和waitchild()函数的良好编程实践。

2026-03-28 15:53:59 388

原创 虚拟地址空间与进程控制

进程地址空间,以及为什么要存在虚拟地址空间,有了虚拟地址空间,进程的创建,终止和等待。

2026-03-22 17:49:27 420

原创 虚拟地址空间

本文探讨了Linux系统中的虚拟地址空间概念。首先分析了Shell内建命令与普通命令的区别,指出内建命令如echo、pwd是Shell内部函数调用,不依赖PATH环境变量。然后通过C程序示例展示了虚拟地址空间的布局,包括代码段、全局变量区、堆区、栈区等。重点通过父子进程修改全局变量的实验,揭示了虚拟地址与物理地址的映射关系:当子进程修改全局变量时,操作系统通过写时拷贝机制在物理内存创建新副本,同时保持虚拟地址不变。这解释了为何父子进程能看到相同虚拟地址但不同变量值的现象,体现了进程独立性和虚拟地址空间的本质

2026-03-18 15:30:08 344

原创 环境变量与虚拟地址空间

环境变量通过 PATH 指定命令的搜索路径,用户执行可执行文件时,系统会在 PATH 指定的路径中查找。通过 echo $PATH 可查看当前路径配置。代码中可通过 main 函数的 env 参数或 extern char **environ 获取环境变量表。环境变量的操作添加:使用 export 命令将本地变量提升为环境变量,如 export TEST_ENV=123456789。删除:使用 unset 命令取消环境变量,如 unset TEST_ENV。查看:通过 env 或 echo $变量

2026-03-16 20:16:17 378

原创 命令行参数和环境变量

文章摘要:本文介绍了C语言main函数的命令行参数用法。通过示例代码演示了argc(参数个数)和argv(参数数组)的使用方法,其中argv[0]始终是程序名,后续元素为命令行参数。重点说明了三个细节:1) argc≥1;2) 参数以空格分隔;3) argv数组以NULL结尾。文章还解释了命令行参数的实用价值,即通过不同选项实现程序的不同功能,并提及了在Linux和VS2022环境下的不同使用方式。

2026-03-13 08:14:35 47

原创 linux进程调度

摘要:Linux O(1)调度算法采用双链表设计,将进程控制块(task_struct)与链表节点分离,实现灵活的数据结构复用。调度队列使用优先级数组(queue[140])和位图(bitmap[5])快速定位进程,时间复杂度为O(1)。为解决进程饥饿问题,采用active/expired双队列轮换机制,当活跃队列空时交换指针。优先级调整在队列交换时完成,同时支持抢占式调度,通过保存/恢复上下文实现进程切换。该算法通过巧妙的数据结构设计,兼顾了调度效率和公平性。

2026-03-12 15:11:51 363

原创 进程的优先级切换

你的电脑上有很多的资源,需要分配资源的先后顺序设置优先级:决定进程获得某种资源的先后顺序在linux中,由task_struct中的nice来修改优先级数据在你初始创建一个进程的时候PRI(Priority,优先级的缩写)的初始值默认是80,以80为基准系统实际的优先级是:PRI(实)=PRI(基准)+nice;如何修改nice呢?top+r+pid(进程的pid值)+nice(想把nice修改为多少)所以PRI的范围也固定了,为60到99。

2026-03-09 09:38:01 217

原创 用队列实现栈

用两个队列实现栈简单版

2025-03-31 11:37:50 1505

原创 数据在内存中的存储

我们从上述整数的存储中知道n数据在整数的储存如果所示,执行上述代码打印的值为。我们直到,int类型是占4个字节的,1个字节是占8个比特的,这说明浮点数存储和整数是不同的,那浮点数是怎么存储的呢?S 表⽰符号位,当S=0,V为正数;• M 表⽰有效数字,M是⼤于等于1,⼩于2的。在讲解浮点数的存储时,先引入一道有趣的代码题。一个int类型通过二进制转化得到32位。例如,如果我定义一个int n=4,那么,数据是如何存储的呢?可以把内存想象为多个格子。

2025-03-19 23:30:02 176

原创 多种方法实现合并两个有序数组

这时候我们可以考虑把对比后的结果放在nums1中无效数据的那片空间,就算最极端(nums2最小的数据也大于nums1中最大的数据)也可以放下nums2;让我们思考一下为什么要创建额外的数组,是因为如果把对比后的结果直接存储在nums1中的话会覆盖nums1中原本的数组内容,哪有没有办法不开辟新的空间来实现存放对比后的结果呢?这里与冒泡排序的区别就是冒泡排序是在一个数组里面,而题目给的是两个数组,所以可以合并成一个数组,再用冒泡排序。当然还可以提升一下,让时间复杂度为O(N),空间复杂度为O(1);

2025-03-17 13:36:26 880

原创 c语言实现扫雷游戏

扫雷游戏默认为9*9个格子随机布置10个雷可以排查雷的坐标 ->通过输入坐标点形式例如:2 3表示坐标为(2,3)的坐标如果该位置不是雷,那么显示该坐标9宫格内有几个雷如果该位置是雷,则被炸死且游戏结束如果把不是雷的位置全部排查完,则游戏结束,排雷成功。

2025-02-20 23:15:56 2006

空空如也

空空如也

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

TA关注的人

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