
linux操作系统
文章平均质量分 88
以实践为线索,逐步带大家理解并且深入了解linux操作系统
稻草人敲代码
懒得写简介
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
进程关系和守护进程
会话是一个或者多个进程组的集合,一个会话可以包含多个进程组。每一个会话也有一个会话ID。会话的主要作用是提供一种机制,以便将相关的进程组织在一起,并对它们进行统一的控制。我们在上面的例子中就可以看到会话ID从上面结果来看,sleep 100 、sleep 200、sleep 300用管道连接之后组成了一个进程组,而且还同属于一个会话ID。作业是针对用户来讲,用户完成某项任务而启动的进程,一个作业既可以只包含一个进程,也可以包含多个进程,进程之间互相协作完成任务, 通常是一个进程管道。原创 2024-07-25 13:01:52 · 1244 阅读 · 0 评论 -
【多线程】线程安全的单例模式
单例模式是一个设计模式,其目的是确保一个类只有一个实例,并提供一个全局的访问点来访问该实例。单例模式常用于需要控制资源数量的场景,比如数据库连接池、日志管理器等。下面介绍常见的单例模式的实现方式。原创 2024-07-17 12:56:43 · 839 阅读 · 0 评论 -
【线程安全】关于死锁问题
如果允许有外部干预,比如把其中某个人的资源强行释放给对方,比如强行把A的苹果拿给B,B收到苹果就把梨释放了,A也就拿到了梨。这样就AB就脱离了死锁状态。死锁检测算法用于在系统允许死锁发生的情况下,定期或在特定情况下检测系统是否处于死锁状态,并采取措施恢复。通过上面的例子,首先苹果和梨同一时间只能时是A或者B拥有,这就满足了。,对于B也是这样,如果没有外部干预,AB就进入了一直等待的情况即。A有一个苹果,B有一个梨,但是A想要的是梨,B想要苹果。A等梨,但是又不释放苹果,这就是。,这里就不做介绍了。原创 2024-07-15 15:04:13 · 606 阅读 · 0 评论 -
【多线程】线程池的原理及其实现
在有任务时就将其分配给某个线程执行,当线程执行完自己的任务之后并不会销毁而是等待下一个任务。,特别是在处理大量短时间任务时。简单来说,线程池就是。原创 2024-07-12 17:10:59 · 557 阅读 · 0 评论 -
【POSIX信号量】基于环形队列的生产消费模型
同样的,整个模型有1个数据缓冲区即环形队列,2个角色即生产者和消费者,3种关系即生产者和生产者、生产者和消费者、消费者和消费者之间得到关系。如果缓冲区已满,生产者将释放互斥锁并继续检查缓冲区状态,直到有空闲空间。POSIX和System V一样,都是unix下的一套管理方法,下面介绍POSIX标准下的信号量。之前的生产者消费者模型是基于阻塞队列queue来实现的,其空间可以动态分配,依靠互斥锁和条件变量来实现同步机制。V信号量作用相同,都是用于同步操作,达到无冲突的访问共享资源的目的。原创 2024-07-12 13:38:00 · 891 阅读 · 0 评论 -
【多线程】生产者消费者模型(代码实现)
生产者消费模型是一种常见的多线程编程模式,广泛应用于解决并发编程中的数据共享和任务调度问题。在该模型中,我们将生产数据并放入缓冲区的线程称为生产者线程,反之,从缓冲区中获取数据的线程就称为消费者线程。生产者和消费者通过共享的缓冲区进行通信,并且使用同步机制(如互斥锁和条件变量)来协调操作,防止数据竞争和资源浪费。缓冲区是指一个用来存放数据的数据结构,通常是一个队列。为了便于记忆,可以将生产者消费模型看成是由。原创 2024-07-10 21:36:10 · 862 阅读 · 0 评论 -
【多线程】线程同步--条件变量的原理及其使用
线程同步意味着在多线程并发执行中,协调线程之间的执行顺序,以确保共享资源被正确访问和修改。线程同步的维护本质就是在安排线程之间的执行顺序。那么在linux中是如何维护线程同步的呢?本篇文章将围绕这个为题展开叙述。动态初始化cond:要初始化的条件变量attr:条件变量的属性,通常是NULL静态初始化。原创 2024-07-10 19:37:03 · 1123 阅读 · 0 评论 -
【线程安全】线程互斥的原理
即使是多处理器平台,访问内存的 总线周期也有先后,一个处理器上的交换指令执行时另一个处理器的交换指令只能等待总线周期。线程互斥(Mutual Exclusion)是多线程编程中的一个重要概念,用于解决。要想做到一个线程访问临界区时阻止其它线程访问,我们就需要使用到。:指向互斥锁属性对象的指针。对某个互斥量进行加锁或者解锁,成功返回0,失败返回错误码。为了方便阐述,后面出现的锁和互斥量不做过多区分。表示上锁(),上锁之后其他线程不能访问临界区,上图中表示使用互斥锁实现线程互斥的示意图,原创 2024-07-09 14:06:15 · 2142 阅读 · 0 评论 -
【Linux多线程】线程的终止、等待和分离
需要注意,pthread_exit或者return返回的指针指向的内存单元应该是全局的,因为线程终止之后其函数栈帧会销毁,之后才会返回一个void*指针。并且,如果不对这些已经终止但是还没有被释放空间的线程做处理,往后继续创建新线程都不会复用前面退出线程的地址空间,这就造成了。观察上面代码运行情况,发现当线程return之后确实被终止了(上图多出来一个线程是库里面的管理线程,不必理会)。,比如线程一处理上半段数据,线程二处理下半段数据,如果其中任何一个线程没有终止,那总数据就会不完整。原创 2024-06-05 23:28:01 · 1558 阅读 · 0 评论 -
【Linux多线程】LWP和pthread_t
每当使用pthread_create创建一个线程时,在底层内核会生成一个LWP实体,就跟创建进程时会生成PCB实体一样,只不过LWP更轻量。除此之外,pthread_create还会在用户空间上生成pthread_t类型的标识符,前者用于用户操作(如等待线程结束、取消线程等),后者用于内核管理。LWP本质是一个描述线程的一个概念,因为linux中没有单独为线程设计一套管理方案,又为了与进程PCB区分开(LWP是Linux中线程的具体实现形式,在linux中,进程和线程本质上都是相同的,都是通过。原创 2024-06-05 15:53:15 · 1099 阅读 · 17 评论 -
【Linux多线程】认识多线程&&创建线程
进程是正在运行的程序的实例,而线程(thread)是进程中的一个执行路线。一个进程可以拥有多个线程。从程序的角度上来说,线程是一个独立运行程序的片段。当程序运行时,进程把大部分资源合理分配给每个执行流(线程),且所有线程共享进程的地址空间,所以线程实际上就是一个轻量级的进程。下面给出进程中的线程示意图:值得注意的是,windos下的线程是有线程控制块(TCB)的。而linux下的进程控制块和线程控制块都是。原创 2024-05-29 16:11:26 · 1232 阅读 · 0 评论 -
【进程空间】通过页表寻址的过程
我们知道每个进程都有属于自己的虚拟地址空间,且每个进程的虚拟地址都是统一的。要想通过虚拟地址访问物理地址,我们就需要借助页表来建立映射关系。下面对于如何借助页表来寻址展开详细解释(以32位操作系统为例)。页框(Page Frame)是物理内存中的固定大小的块,通常为4KB。在物理内存中,页框是用于存储实际数据的最小单元。假设内存大小为4GB,也就能划分出1024*1024个页框。当进程通过页表来访问物理地址时,其本质就是找到页框的地址。于是,操作系统对内存的管理,就可以看成是对页框即块的管理。原创 2024-05-28 20:12:42 · 1356 阅读 · 0 评论 -
【进程信号】可重入函数&&volatile关键字
虽然执行了myhandler,也成功修改了flag的值,但是由于编译器优化,早就将flag的值拷贝到寄存器中了,CPU只会在寄存器中读取flag的值。标准情况下,键入 CTRL-C ,2号信号被捕捉,执行自定义动作,修改 flag=1 , while。意思就是说,可重入函数里面的数据都是临时变量,随着函数栈帧的销毁而销毁,编译器在优化代码的时候,会大概推断出哪些变量在特定的范围内不会改变。保持内存的可见性,告知编译器,被该关键字修饰的变量,,对该变量的任何操作,都必须在真实的内存中进行操作。原创 2024-05-22 16:51:01 · 781 阅读 · 3 评论 -
【进程通信】信号的捕捉原理&&用户态与内核态的区别
在之前的学习中,我们已经知道了信号是如何产生的,也知道了进程是如何记录一个信号的。如果进程收到了一个信号且没有屏蔽这个信号,则会将信号编号作为handler数组的下标执行该信号的处理函数。我们将处理特定信号的事件的过程叫做信号的捕捉。下面将带大家了解从操作系统的角度看是如何捕捉信号的。用户态权限有限,户态权限最高。安全性:由于权限较低,用户态不能访问系统核心,较为安全。而内核态具有完全控制权,一旦出错可能导致整个系统崩溃。系统调用:用户态不能执行系统调用,需要切换到内核态。原创 2024-05-21 23:15:16 · 1743 阅读 · 23 评论 -
【进程信号】信号阻塞的原理
每一个位都表示一种信号,如果有信号发送给该进程,那么这个位图对应的信号位就会置为1。观察上面图片,信号的未决表和阻塞表都是位图结构,且每一个比特位的位置都是表示信号的编号。其每一个比特位都表示一个信号编号,如果是1则表示该对应信号被阻塞,即使信号到达,进程也不会处理。功能:初始化一个空的信号集,即将信号集中所有信号清楚,也就是让信号集中的每一个比特位清0。对于信号的学习,我们将其分为三个部分:产生信号、接收信号、处理信号。,显然,对handler数组某一元素内容的修改,即修改某一信号的响应方式。原创 2024-05-16 19:59:47 · 964 阅读 · 0 评论 -
【进程通信】了解信号以及信号的产生
信号是进程通信的一种方式。如同我们按下ctrl+c就能终止一个进程,实际上就是bash进程向子进程发送了一个终止信号。和手机信号,wifi信号等类似,进程之间也可以通过信号来传递某种信息。不同的是,进程之间的信号本身就是一种共享资源。信号是如何产生的?被谁产生的?又是怎么获取信号的?本篇文章将从这几个问题展开叙述,详细讲解信号产生的原理。所有的信号本质上都是又操作系统产生的。只不过是进程委托操作系统将这个信号发送给另一个进程(也可以是自己)。告诉某个进程发生了什么。怎么做由开发者决定。原创 2024-05-12 20:01:00 · 1315 阅读 · 16 评论 -
【进程通信】Syetem V 共享内存(结合代码模拟通信)
进程之间除了使用管道来进行通信,还能通过申请共享内存的方式使多个进程访问同一片共享资源。下面介绍System V标准下的共享内存是如何使进程间通信的。共享内存是进程通信最快的方法,因为没有额外的拷贝过程,直接对内存进行读取。此外,共享内存并不保证通信的同步数据在读取之后不会自动清空释放,也就意味着无论何时只要想读就能读。所以很多时候,为了保证数据的同步性,即写入端进程写入数据后才让读端进程读取数据,我们可以让管道做一个提示作用。原创 2024-05-03 15:48:54 · 1852 阅读 · 3 评论 -
【进程通信】用命名管道模拟server和client之间的通信
当了解了的通信机制只能用于之间时,似乎是出于本能的提出疑问–如果两个进程没有任何关系呢?假如两个进程之间没有血缘关系,彼此进程就没法轻易拥有对方的,即不能看到同一份共享资源。这时候我们需要除了pipe函数创建管道的另一种方法,可以支持任意两个进程看到同一份。于是可以考虑使用。命名管道是一个。,创建管道时,以后其它进程就可以通过这个名字来使用这个管道的另一端。这也是为什么我们称这样的管道为命名管道。命名管道是以一个出现的,包括。原创 2024-05-01 17:27:23 · 1235 阅读 · 1 评论 -
【进程通信】利用管道创建进程池(结合代码)
我们知道,一个进程创建子进程通常是为了让这个子进程去为它完成某个任务。例如我们使用的指令,其实就是bash进程创建子进程让子进程去执行的。每创建一个进程我们都用一个结构体(或者类)维护,于是对工作进程的管理就变成了对结构体的管理,整个进程池从代码角度上来说就是一个结构体数组。于是我们可以提前创建出一批进程,当有任务要做的时候就从这一批子进程中拿出一个空闲的去执行,一旦某个子进程把任务执行完之后也不立即销毁进程,而是等待下一个任务的来临。我们把进程池中的进程也称为。Process.cpp文件。原创 2024-04-28 21:18:13 · 286 阅读 · 0 评论 -
【进程通信】进程通信--匿名管道
进程通信(IPC,Inter-Process Communication)是指不同进程之间传递数据或信号的机制。这是一种能在运行中的程序之间协调或者交互信息的技术。尤其是在操作系统中,不同的进程可能通过某种方式来共享数据。每个进程都是相互独立的,一般要通过第三方操作系统(OS)提供通信的方式才能实现两个进程通信。进程通信的本质其实就是让不同的进程看到同一份资源(文件、内存、内核级缓冲区等)。不同的通信方式具体的实现原理也会有不同。原创 2024-04-28 15:51:27 · 1088 阅读 · 1 评论 -
【基础IO】谈谈动静态库(怒肝7000字)
在软件开发中,库(Library)是一种方式,可以将代码打包成可重用的格式,供其他程序调用。库可以分为静态库StaticLibraries)和动态库DynamicLibraries 或 Shared Libraries)。这两种类型的库在链接和执行时有各自的特点和用途。本篇文章将围绕动静态库的原理及其使用展开讲解。原创 2024-04-20 22:29:18 · 1239 阅读 · 23 评论 -
【基础IO】结合代码理解软硬链接(超详细)
结合对前面对文件系统的理解,inode其实是一个指向文件数据的一个指针。创建软链接,其实就是创建了另一个指针,指向的是原始文件的路径。指令删除文件时并不会考虑该文件是否是一个软链接,也就不会影响到原来的文件。即使逻辑上看起来有循环引用的风险,物理层面上的目录结构并未形成真正的闭环,因此遍历操作不会陷入无限循环。假设我们试图遍历目录A的内容时,会找到B,进入B之后又回到了A,此后这个过程便无限循环下去了。:软链接是一个独立的文件,有着自己独立的inode。总的来说,这是操作系统操心的事,我们无需心其细节。原创 2024-04-19 11:35:22 · 1425 阅读 · 0 评论 -
【基础OI】深入理解linux文件系统
我们知道,一个进程通过文件描述符来标识一个打开的文件,进程拿着描述符就可以在内核中找到目标文件并对其进行各种读写操作。在此之前,文件存储在磁盘中,操作系统是如何在偌大的磁盘中找到自己想要的文件并打开的呢?对于这些没有被打开的文件,操作系统又是如何做管理的呢?本篇文章将带领大家较为深入的理解linux的文件系统。磁盘是计算机的主要存储介质,可以存储大量的二进制文件,并且断电也不会丢失数据。下面就是一个磁盘。原创 2024-04-12 11:18:49 · 1366 阅读 · 2 评论 -
【进程OI】重定向的本质&&用户级缓冲区
这在需要重定向文件描述符或管理多个文件描述符的场景中非常有用。观察以下代码:以上代码的大致执行过程:1.打开文件。原创 2024-04-03 18:02:58 · 1027 阅读 · 0 评论 -
【进程IO】详细讲解文件描述符fd
C语言的关于文件操作的各种函数实际上是对系统调用的封装。那么从进程的角度看,一个文件到底是如何被描述的呢?又是如何被组织并管理的呢?C语言关于文件概述以及文件操作关于文件的系统调用。原创 2024-03-30 23:54:00 · 1359 阅读 · 0 评论 -
【进程OI】基本文件操作的系统调用
当用户想要向磁盘中的文件读写数据,就必须要得到操作系统的允许。同样,操作系统为了能让用户去对文件进行打开、读写、关闭等操作,向上提供了相应的系统调用的接口。C、JAVA、C++等语言它们对这些系统调用进行了封装,虽然各个函数看起来不一样,但是本质是都是在使用操作系统提供的系统调用。接下来,我们来介绍这些系统调用的接口。原创 2024-03-30 16:00:15 · 806 阅读 · 1 评论 -
【linux课设】自主实现shell命令行解释器
shell是命令解释器,它接收用户的命令并将其传递给内核去执行。bash,即GNU Bourne-Again Shell,,也是大多数linux系统下默认的shell。原创 2024-03-29 23:32:25 · 896 阅读 · 0 评论 -
【进程控制】进程程序替换的原理以及exec函数族
这个新程序将替换掉原先正在执行的程序,成为该进程的新执行体,且会继承原先进程的一些属性,比如进程PID等。例如我们的bash进程执行命令。本来作为bash的子进程,代码和数据都是基本一致的,但是根据实际需求,子进程需要执行指令,也就需要将指令程序替换进来。包括PID和PPID,在我们看来,程序被替换后可能执行完全不同的程序,这是我们程序员能直接感受到的。表示命令行参数数组,以命令名为首,以NULL结尾。有七种以exec开头的函数,可以实现进程的程序替换。以上函数功能相似,在不用的场景下选择合适的函数。原创 2024-03-28 23:07:56 · 1051 阅读 · 0 评论 -
【进程控制】超详细讲解wait和waitpid的原理(结合代码)
在了解了进程状态这一概念之后,我们明白了什么叫做僵尸进程:子进程退出,父进程“不管不顾”。而一旦存在僵尸进程,势必也会存在内存泄露问题,所以作为一个父进程,及时处理子进程的退出信息是他的责任。那么子进程的退出信息到底是什么?以及父进程怎么接收到子进程的退出信息?本文章重点围绕这两个问题展开叙述。进程等待进程等待是指一个进程暂停执行,等待另一个进程的结束。最常见的是父进程等待自己的子进程,或者父进程回收自己的子进程资源包括僵尸进程。等待方法有:wait函数和waipid函数。原创 2024-03-27 22:55:11 · 4555 阅读 · 2 评论 -
【进程控制】谈谈进程终止的三种状态
处理的,正常情况下,对用户进程而言是不可见的。如果一个进程执行了一条非法的指令,那么内核就发送给它一个SIGILL信号(4)。维护着待处理信号的集合,假如发送了一个k类型的信号,内核就会设置pending中的第k位,而只要接收了一个类型为k的信号,内核就会清除pending中的第k位,表示该信号已经被接收。如果一个进程有一个类型为1的待处理信号,那么任何接下来发送到这个进程的所有1类型的信号都不会被排队等待,而是直接被丢弃。return在普通函数中返回的是函数的结果,而在main函数里返回的就是退出码。原创 2024-03-27 17:42:26 · 2082 阅读 · 0 评论 -
【进程调度】Linux内核的进程调度队列--runqueue
至此我们清楚了系统是如何查找一个合适的进程被CPU调度的,这种调度算法的时间复杂度是O(1)的,不随着进程的增多而导致时间成本的增加,我们将其称之为进程调度O(1)算法。原创 2024-03-25 23:09:10 · 1389 阅读 · 1 评论 -
【进程概念】虚拟内存与页表简述
一个系统中的进程是与其他进程共享CPU和主存资源的。早期的PC使用物理寻址,而且诸如数字信号处理器、嵌入式微控制器以及Cray超级计算机这样的系统仍然继续使用这种寻址方式。然而现代处理器使用的是一种称为虚拟寻址(virtual addressing)的寻址形式。原创 2024-03-25 16:51:24 · 1287 阅读 · 0 评论 -
【进程概念】环境变量PATH(结合代码,超极容易理解)
当我们运行一个程序时,该程序可以看到该系统的环境变量表,其中main函数中的第三个参数就是记录着所有的环境变量(本质上是一个指针数组)。bash进程时test2进程的父进程,在bash进程中修改了环境变量,其子进程test2也会收到一份几乎一模一样的环境变量表,也就能找到我们刚才的变量MYENV了。再比如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是。命令export可新增,修改或删除环境变量,供后续执行的程序使用。原创 2024-03-24 20:07:21 · 2245 阅读 · 1 评论 -
【进程概念】进程的优先级PRI和NI
进程的优先级代表着cpu资源分配的先后顺序,也叫做。一般来说,优先级越高的进程先对来说越重要,越重要的越容易获得cpu.这样可以使进程调度变得更加灵活,也使得整体的系统性能得到改善。那如何描述一个进程的优先级呢?换句话说就是擦做系统是怎么知道操作系统是如何比较进程的优先级的呢?之前我们学过进程是如何被描述的。在linux中,用task_struct描述一个进程,原创 2024-03-24 15:38:54 · 705 阅读 · 0 评论 -
【进程概念】进程状态以及僵尸进程(结合代码)
而在task_struct里,其实也就是用一些变量来表示进程状态,其中state表示的就是进程的当前状态,state定义在 Linux 源文件 include/linux/sched.h 头文件中.-1 就表示不能运行,0表示运行,大于0表示停止。(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。而僵尸进程已经终止了,内核还在保留着他的退出信息知道父进程回收为止,与僵尸类似。表示一个进程死亡,CPU会进行资源的回收。原创 2024-03-22 16:39:14 · 1371 阅读 · 3 评论 -
【创建进程】fork函数与写时拷贝
返回值:自进程中返回0,父进程返回子进程id,出错返回-1fork函数是一个Unix/Linux系统中常用的,用于。fork函数的工作原理是,包括代码段、数据段、堆栈等,但是。。。一个函数,这是令人感到奇怪的,我们可以通过代码来观察该现象观察以下代码:我们可以发现,fork函数确实返回了两个值,对于父进程而言,拿到的的就是子进程的pid.对于新建立出来的子进程来说,fork返回值就是0.(27502是bash进程)原创 2024-03-22 09:30:26 · 779 阅读 · 21 评论 -
【进程概念】进程控制块task_struct-PCB
进程是什么?如何描述进程?为什么要描述进程?原创 2024-03-21 18:08:31 · 969 阅读 · 0 评论 -
操作系统:一款纯正的“管理”软件
微软的windows,苹果的macos以及linux都是市面上常见的计算机的操作系统(Operator System,简称OS)。虽然随着时代的发展以及操作系统版本的不断迭代,各种操作系统都拥有属于自己的特色,但无论是哪一款操作系统,它们的“使命”都是一致的:管理软件和硬件资源。接口即计算机系统中两个独立的部件进行信息交换的共享边界应用程序和操作系统之间存在接口,操作系统和计算机硬件之间也存在接口。通过接口可以实现应用程序与操作系统之间的通信和操作系统和计算机硬件之间的通信。原创 2024-03-13 16:35:33 · 1009 阅读 · 1 评论 -
冯诺依曼模型
内存的特点:存储容量和读取写入数据的速度都介于CPU寄存器和硬盘之间,由于有比寄存器较大的容量,我们可以提前往内存区域存入“可能被读取的数据”,也就是预装数据,这样一来,CPU就不会傻傻等硬盘写入数据,而是直接到内存中读取,并且,内存的速度也不慢(相比于硬盘等外设)。我们可以看到,CPU中寄存器的读取速度是最快的,体积是最小的,磁盘等外设的速度是最慢的,体积是最大的,并且两者的速度差太大!而控制器就相当于大脑,给身体各个部位下达各种指令,运算器就相当于我们的手,直接干活的部位。原创 2024-03-13 13:13:20 · 1285 阅读 · 1 评论 -
如何在vs上提交代码到gitee/github?
使用vs提交代码到gitee/github仓库原创 2024-03-11 21:56:20 · 892 阅读 · 2 评论