- 博客(129)
- 收藏
- 关注
原创 第五部分:7---信号的捕捉
信号递达期间,该信号会被屏蔽直到递达完成。当某个信号的处理函数被调用时,内核自动将当前信号加入进程的信号屏蔽字block中,当信号处理函数返回时自动恢复原来的信号屏蔽字。这样就保证了在处理某个信号时,如果这种信号再次产生,那么 它会被阻塞到当前处理结束为止。如果在调用信号处理函数时,除了当前信号被自动屏蔽之外,还希望自动屏蔽另外一些信号,则用sa_mask字段说明这些需要额外屏蔽的信号,当信号处理函数返回时自动恢复原来的信号屏蔽字。sigaction实现信号的捕捉:sigaction接口的功
2024-09-27 20:29:27
387
原创 第五部分:6---信号的递达
信号的递达流程:信号被生成后加入未决信号集,等待处理。如果信号被阻塞,则暂时不能递达;如果没有被阻塞,则可以递达并处理。如果信号未被阻塞,先从未决信号集中移除信号,再依据可处理信号集的设定执行默认操作或调用自定义处理函数。如果信号被阻塞,解除阻塞后,该信号需要被“立即”递达。信号在什么时候递达?进程在内核态返回到用户态时,进行信号的检测和处理。用户态和内核态:用户态是一种受控的状态,所能够访问的资源有限。内核态是操作系统的工作状态,能够访问大部分的系统资源。内核态、用户态在
2024-09-27 20:27:04
1263
原创 第五部分:5---三张信号表,信号表的系统调用
信号的递达、未决、阻塞:信号的处理动作称为信号的递达。从信号产生到实际处理之间的状态称为信号未决。未决的信号保存在PCB的pending表中。信号可以被阻塞,这种状态称为信号阻塞,即信号被暂时保留不会立即递达。阻塞的信号保存在pending表中,直到阻塞解除后才被递达,也就是阻塞表block中对应信号位置被设为0。进程维护的三张信号表:每个进程维护三张表,用于管理信号:block表:表示是否对信号进行阻塞,1为阻塞,0为不阻塞。也成为信号屏蔽字表。pending表:即未决位图表,
2024-09-27 20:23:18
640
原创 第五部分:4---Linux闹钟机制
闹钟机制:Linux 的闹钟机制为用户提供了一种设置和管理闹钟的方式。用户通过系统调用设置闹钟,操作系统负责在指定时间后处理这些闹钟。闹钟结构体和链表:操作系统为每个闹钟创建一个结构体对象,这个对象包含有关闹钟的信息,例如时间戳、信号类型、闹钟id、进程pid、处理函数指针等。操作系统维护一个链表或其他数据结构来存储这些闹钟对象。每当用户设置一个新闹钟,操作系统会将其添加到链表中。
2024-09-27 20:21:16
437
原创 第五部分:3---信号的介绍、产生、保存、处理
信号的概念:信号是进程间通信的一种异步通知机制,用于向目标进程发送通知。信号的处理是异步的,意味着信号可以在任何时候产生,而进程会在适当时机对信号作出处理。异步的概念:异步(Asynchronous)是指在编程或系统设计中,任务的执行不需要立即等待其他任务完成,而是可以在不阻塞的情况下继续进行。信号的3种处理方式:信号有三种处理方式:默认处理,忽略,自定义处理(捕捉)。信号的捕捉,就是对信号设置自定义信号函数,signal函数会直接修改信号表中对应信号的处理函数指针,使其指向自定义信号
2024-09-27 20:20:08
798
原创 第五部分:2---中断与信号
中断机制是CPU和外设之间的一种直接通信方式,当外设(例如键盘、硬盘等)有需要服务的请求时,会通过发送中断信号告知CPU。CPU引脚和中断号的关系:CPU有专用的引脚来接收外设发出的中断信号。这些引脚通常用于接收外设发出的“中断请求”(Interrupt Request, IRQ)。不同外设可能对应不同的IRQ线路,这样CPU可以根据收到的IRQ来区分是哪一个外设发出的中断。当外设通过IRQ线路发送信号后,CPU会通过一个专门的寄存器(通常叫做中断请求寄存器,Interrupt Request R
2024-09-27 20:16:44
328
原创 第五部分:1---进程的前后台管理
使用 “ctrl + z” 发送SIGTSTP(暂停信号),将当前前台进程暂停并放入后台,shell 则自动回到前台。使用 “ctrl + c” 发送 SIGINT(2号信号)用于终止前台进程,后台进程不会被此信号终止。使用 “fg + 后台进程编号” 可以将后台进程切换到前台,shell 则会被切换到后台。ctrl+z 后进程被暂停,使用bg 命令,将暂停的后台进程继续运行,但不会切换回前台。前台进程:只能有一个前台进程,能够接收用户的输入,因为键盘是唯一的输入设备。
2024-09-27 20:12:36
311
原创 第六部分:1---进程间通信,匿名管道
创建单向管道:管道的本质是内存中的一块缓冲区,在使用 pipe() 系统调用创建单向管道时,内核会自动为管道分配两个文件描述符:一个用于读端,一个用于写端。这两个文件描述符分别对应这块缓冲区的读指针和写指针。注意,管道的读写端不是直接通过文件打开两次实现,而是通过 pipe() 生成一个匿名的内存缓冲区(管道),分别分配给读端和写端。父进程fork() 后,子进程会继承父进程的文件描述符表。这意味着子进程会复制父进程的文件描述符表项,指向同一个内核文件表项和缓冲区。因此,父进程和子进程都拥有两个文件
2024-09-19 00:21:54
1122
原创 第五部分:3---前后台进程的管理、闹钟机制
前后台进程的管理:前台进程:只能有一个前台进程,能够接收用户的输入,因为键盘是唯一的输入设备。后台进程:可以有多个,但后台进程不能直接接受来自键盘的输入。使用 jobs 命令可以查看当前所有的后台任务,每个后台任务都有一个编号。使用 “fg + 后台进程编号” 可以将后台进程切换到前台,shell 则会被切换到后台。使用 “ctrl + c” 发送 SIGINT(2号信号)用于终止前台进程,后台进程不会被此信号终止。使用 “ctrl + z” 发送SIGTSTP(暂停信号),将当前前台
2024-09-19 00:09:33
349
原创 第五部分:2---信号的介绍、产生、处理
信号的概念:信号是进程间通信的一种异步通知机制,用于向目标进程发送通知。信号的处理是异步的,意味着信号可以在任何时候产生,而进程会在适当时机对信号作出处理。异步(Asynchronous)是指在编程或系统设计中,任务的执行不需要立即等待其他任务完成,而是可以在不阻塞的情况下继续进行。信号表的继承:每个进程都有一张信号表,本质是一个函数指针数组,数组的下标就对应每一个信号。当使用fork()系统调用创建子进程时,子进程会复制父进程的信号处理表。这意味着父进程如何处理信号,子进程刚被创建
2024-09-19 00:07:51
848
原创 第五部分:1---中断与信号
CPU上面有一个个针脚,这些针脚有编号,当某个外设通过针脚直接向 CPU 发送中断信号,CPU中的某一个寄存器会记录当前发送中断的针脚的编号,这个编号就叫做“ 中断号 ”。中断是硬件与 CPU 之间的直接通信机制,当外设(如键盘)就绪或需要服务时,会向 CPU 发送中断信号,通知 CPU 进行处理。CPU 通过读取寄存器的中断号,就会得知那个外设资源就绪了,就会通过中断号调用中断向量表中的函数来处理外设请求。不是所有硬件都能发出中断信号,中断针脚是有限的,但大多数常用硬件都支持中断机制。
2024-09-19 00:06:05
423
原创 第四部分:2---文件内核对象,文件描述符,输出重定向
struct file 是在内核空间中创建的用于描述文件的结构体, 每当一个文件被打开时,内核会为该文件创建一个对应的 struct file 结构体,并在文件描述符表中为其分配一个文件描述符。基于文件的定义(文件 = 内容 + 属性),struct file 结构体包含了文件的各种属性,文件的操作方法,指向文件缓冲区的指针。修改文件属性,可以直接操作struct file的成员实现。修改文件内容,需要通过指向文件缓冲区的指针来操作。而缓冲区是内存中的一块区域,用于暂时存放文件的数据。当文件被读
2024-09-13 00:49:01
721
原创 第四部分:1---文件基础理解、C语言文件操作、Linux系统文件接口、使用一个变量传递多个标志位
文件是如何组成的? 文件由两部分组成:文件的内容和文件的属性。 文件内容是数据,文件属性也是数据。因此,文件内部存储文件的内容数据和属性数据。 对文件操作的本质是什么? 对文件的操作就是对文件内容或文件属性的操作。操作文件属性可以包括更改文件权限、修改时间戳等,而操作文件内容则是读写文件中的数据。 文件被打开的本质是什么: 文件可以分为已经打开的文件和未被打开的文件。要操作的就是被打开的文件==加载到内存的文件。 打开一个文件,实际上是操作系统将文件从磁盘加载到内存的过程。这个过程需要操
2024-09-13 00:46:06
921
原创 1.滑动窗口问题
核心思想:滑动窗口的核心思想是使用两个指针(或索引)来标记窗口的左右边界,并动态调整窗口的大小和位置,以在一次遍历中解决问题。窗口在遍历过程中“滑动”或者“移动”,使得算法能够在数据结构中找到所需的子序列,而无需反复遍历相同的子序列。处理思路:通常,窗口的初始大小为 0,即两个指针都指向数据结构的起始位置。右指针向右移动,扩展窗口的右边界,包含新的元素。在每次右指针移动后,检查当前窗口是否满足特定条件(如无重复字符、窗口内的元素和满足某个值等)。如果满足条件,可以记录或更新结果。
2024-09-10 22:19:40
882
1
原创 第三部分:6---进程程序替换
通过 fork 创建的进程,在最初会执行父进程代码的一部分,这通常包括 fork 之后的代码分支。父进程和子进程在 fork 调用后会继续执行相同的代码,但它们在不同的进程上下文中独立运行。如果希望 fork 创建的子进程执行与父进程完全不同的代码并处理新的数据,从而不再与父进程有任何关联,则需要进行进程程序替换。这通常是通过 exec 系列函数实现的。进程程序替换的目的,就是将子进程的当前进程映像替换为一个新的程序映像,使得子进程能够执行与父进程无关的代码,并处理与父进程不同的数据。这一操作使得子
2024-09-10 22:14:26
881
原创 第三部分:5---进程等待、进程终止
进程的两种终止方式:正常终止:当进程完成其所有任务后,自行结束,并返回一个退出码。这个退出码通常通过 main 函数的返回值或 exit() 函数指定。正常终止的进程会将退出码传递给操作系统和父进程,用于告诉其结束原因。异常终止:当进程在运行过程中因某种原因未能正常完成而被迫终止。这通常是由于进程收到来自操作系统的信号,例如 SIGKILL 或 SIGSEGV。信号可能由用户(用户可以手动向进程发送信号使其终止,例如:“ kill -9 pid ”)、操作系统或其他进程触发,表示进程需要立即停止。异常
2024-09-10 22:11:27
1055
原创 第三部分:4---进程地址空间
程序地址空间的本质是操作系统内核管理的一个数据结构,它用于描述和管理一个进程所能访问的所有虚拟内存地址。地址空间中的内存区域通常被划分为多个小块,每个小块对应一个特定的用途,如代码段、数据段、堆区、栈区等。这个数据结构的核心是一个或多个结构体,这些结构体包含了对每个内存小块的描述信息,包括起始地址、结束地址、访问权限(如可读、可写、可执行)等。程序地址空间仅仅是对进程虚拟内存的逻辑描述,并不是实际的物理内存。它定义了进程在运行时可以访问哪些虚拟地址,而实际的物理内存是由操作系统通过页表等机制进行
2024-09-10 22:07:02
786
1
原创 第三部分:3---环境变量
环境变量是一个全局变量,系统中存在大量的环境变量,存在新式是以键值对的方式存在。每一个环境变量都有特殊功能,用于完成特定的系统功能。环境变量可以被系统中运行的任何进程访问。环境变量可以存储:目录路径、文件路径、系统信息、临时标志或状态等等。
2024-09-10 22:03:00
892
原创 第三部分:2---进程理解/Linux下进程初识
操作系统如何管理进程?进程是由操作系统创建的->操作系统是由C语言写的->进程需要被C语言写的操作系统管理->C语言通过结构体管理数据->进程相当于一个个结构体->结构体中的成员是进程的一个个属性。进程的结构体:进程的结构体被称为“进程的PCB”,当进程被创建PCB就会被创建。Linux下PCB叫做task_struct。操作系统如何加载进程?操作系统先将可执行程序从磁盘加载到内存中。操作系统为加载的进程创建PCB,用于管理进程信息。
2024-09-10 21:59:19
1135
原创 第五章:AVL树
AVL树一般包含左右子树指针,父节点指针,平衡因子,自身节点值。平衡因子计算公式为:balanceFactor(N)=height(N.left)−height(N.right)。新建的节点的平衡因子为0;如果平衡因子为0,表示以当前节点为根节点的树的左右子树高度相同,节点是平衡的。如果平衡因子为1,表示左子树比右子树高一层,节点是平衡的。如果平衡因子为-1,表示右子树比左子树高一层,节点是平衡的。如果平衡因子为2或-2,表示节点不平衡,需要通过旋转操作进行调整。
2024-07-25 22:26:02
687
原创 第五章:map和set
set是一种关联式容器,它存储唯一的键,并且这些键按照严格的顺序进行排序。set中的每个元素都是唯一的,不能有重复元素。set会根据元素的值自动进行排序,默认情况下是按照从小到大的顺序进行排序。set的插入、删除和查找的时间复杂度为 O(log n)。set中的底层使用二叉搜索树来实现。multiset 与 set 类似,但允许存储重复的键值。multiset 也基于红黑树实现,保证了高效的元素查找、插入和删除操作,其时间复杂度为 O(log n)。
2024-07-23 12:23:17
988
原创 1.时间复杂度/空间复杂度
斐波那契数列,空间复杂度为O(N),开辟栈空间是一边开辟一边释放的,最多创建到N个,就会开始边释放边开辟,最终不会超过N个。一个未知的变量,Q(N),这个值可能很大可能很小,所以复杂度可能大小变化。斐波那契数列,时间复杂度O(2^N),递归长度为n,每次每项分裂为两项。一个具体的数值,O(1),这个值表示是一个固定值,复杂度是固定的。判断是Q(N)和O(1),主要还是看运行时间是否固定。二分法,时间复杂度O(long N)冒泡,时间复杂度O(N^2)
2024-07-17 18:20:50
320
原创 Qt:25.QSS选择器(类型选择器、类选择器、id选择器、并集选择器、子控件选择器、伪类选择器)
QSS选择器(类型选择器、类选择器、id选择器、并集选择器、子控件选择器、伪类选择器)
2024-07-14 23:38:06
794
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人