![](https://img-blog.csdnimg.cn/20201014180756918.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Linux系统
文章平均质量分 88
Linux相关东西
super_haha_star
这个作者很懒,什么都没留下…
展开
-
文件系统(一)
inode的属性里边包含了一个数据块的数组,这个数组存储的说data里面数据块的地址,当然如果只有15大小的话,只能存储60kb的大小,所以后面的数据块可以指向一个存储着其他数据块编号的数据块,这就叫二级索引,同时二级索引的数据块也可以存储其他数据块儿的inode,这就是三级索引。当我们把fopen,fclose,fread,fwrite等接口写完之后,代码编译之后,形成二进制可执行程序之后,但是没运行,文件对应的操作没有被执行,程序对文件的操作本质是进程对文件的操作!c.缓冲区满--全缓冲--磁盘文件。原创 2023-09-11 11:04:05 · 48 阅读 · 0 评论 -
进程/线程
信号量:允许多个线程同一时刻访问同一资源,但是需要限制在同⼀时刻访问此资源 的最⼤线程数⽬,⼀般是将当前可⽤资源计数设置为最大资源计数,每增加⼀个线程对共享资源的访问,当前可⽤资源计数就会减1 ,只要当前可⽤资源计数是⼤于0 的,就可以发出 信号ᰁ信号。综上:进程是资源分配的基本单位,而线程是调度的基本单位,线程共享进程数据,但也拥有自己的一部分的数据,比如线程id,一组寄存器,栈,errno,信号屏蔽字,调度优先级。线程:在一个程序中的一个执行路线叫做线程,也就是说线程是进程内部的一个控制序列。原创 2023-08-09 23:42:13 · 61 阅读 · 0 评论 -
Linux线程(五)
对于上诉代码,一个线程在操作临界资源的时候,必须临界资源是需要满足条件的,但是对于公共资源是否满足生产或者消费条件,无法直接得知(在没有访问之前,是无法得知的),所以只能先加锁,在检测,在操作,在解锁,也就是说在操作临界资源的时候,有可能临界资源没有就绪,但是我们无法提前知道,所以只能对资源整体加锁,就默认了对资源整体使用。对于生产者而言,看重的是队列中剩余的空间,空间资源定义为一个信号量,对于消费者而言,看中的是放入队列中的数据,数据资源定义为一个信号量。3、最开始的时候一定是先生产,在消费。原创 2023-07-08 21:42:09 · 32 阅读 · 0 评论 -
Linux线程(四)
互斥的原理:把互斥锁当成一个变量,在汇编级别给我们提供CPU寄存器和内存之间数据交换的方式,就能完成互斥的方式。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。3种关系:生产者和生产者之间(互斥),消费者和消费者之间(互斥),生产者和消费者之间(互斥)。条件变量是个变量,需要设置为全局的,是一种类型,给用户提供了等待和唤醒。原创 2023-07-04 19:35:44 · 34 阅读 · 0 评论 -
Linux线程(三)
对于线程1而言,进入临界区,正在访问临界资源期间,可以被CPU切走,去执行其他任务,但是线程1会带走他的寄存器里面的内容一起被切走,再次切换回来的时候,也是带着自己寄存器的内容回来的,并且被切走的时候,是跟锁一块儿切走的,其他线程依旧无法申请锁成功,也无法向后执行,直到线程1释放这个锁。站在其他线程的角度,看待当前线程持有锁的过程是原子的。在线程(二)中说到锁也是一个资源,锁本身就是一个共享资源(临界资源),全局的变量是要受保护的,锁是用来保护全局资源的,锁本身也是全局资源,锁的安全谁来保护呢?原创 2023-07-04 13:21:01 · 28 阅读 · 0 评论 -
Linux线程(二)
首先对于CPU来说,内部的储存数据的寄存器只有一套,是时间片轮转执行每一个进程和线程的,对于执行的代码而言,首先需要将数据放到CPU上,然后CPU进行计算,计算完成之后,返回内存,完成整个的计算过程,如果在返回的途中,线程被轮换了,此时值还没有被写回内存,线程只有带着此时CPU内部寄存器的值(上下文的内容)在旁边等候,此时又进来一个线程,他就会对全局变量在次进行处理,当他处理了很多次之后,时间片轮转,又轮到上一个线程,他会带着他的上下文内容回来继续从断开的地方执行,此时就会导致全局变量的值出错。原创 2023-06-27 21:48:12 · 87 阅读 · 0 评论 -
Linux线程(一)
对于代码而言,你的代码变量地址连贯性越高,高速缓存的命中率越高,也就是,拿本来需要运行的数据的时候,顺带着把一会儿要用的数据也拿进来了,而对于那些不连续的数据结构,链表之类的,地址不连续,相差很远,就需要多次从内存中再次拿取数据,告诉缓存命中率较低。而进程内部可以有多个执行流,每个执行流都指向了虚拟内存这一段空间,进程的资源可以通过虚拟地址空间+页表的方式把自己部分资源分给特定的线程,所以有了进程的概念之后,现在CPU每次执行进程的时候,其实是执行的是一个个线程,也被叫做轻量级进程。原创 2023-06-18 18:31:42 · 58 阅读 · 1 评论 -
Linux信号(二)
当在用户态执行代码的时候,需要执行系统调用接口的时候,需要从用户态--->内核态,当执行完系统调用之后,去task_struct去查看block,pending以及handler这三张表,如果block2号位置为0,pending2号位置为1,此时去handler表中寻找对应的调用,切换到用户态去执行对应的方法,当执行完对应的方法之后,不能直接返回到程序节点的位置,需要再次回到内核态,然后再返回用户态之前的位置。当需要执行OS对应的函数的时候,此时改变CR3寄存器的内容,变成内核态去访问。原创 2023-06-09 16:52:04 · 208 阅读 · 0 评论 -
Linux信号
OS在接收到信号的时候,一般有三种动作,默认,自定义,忽略。其中默认操作就是OS自带的,忽略表示的是OS不对信号做出反应,而自定义则是用户通过调用系统接口去修改OS的操作。其中系统函数是//系统接口//这是一个函数指针这里通过调用signal函数,重写系统的信号,这并不是一定会执行,除非接收到对应的信号。std::cout原创 2023-06-08 11:46:24 · 47 阅读 · 1 评论 -
Linux进程通信--System V
对于申请共享内存和malloc在堆上申请内存是一样的,malloc在申请的时候,会多申请一部分的内存,用来记录这一部分内存的属性,这部分一般被称之为cookie数据。如果没有这部分数据,在free()函数执行的时候,只传入了起始地址,是根本无法完全释放已经申请的内存。所以对于共享内存而言,共享内存=物理内存块+共享内存的相关属性,可以通过申请共享内存的key值保证共享内存在系统中是唯一的,这个唯一的key值还是另外一个进程看到这块儿内存的必要值,key存在于描述共享内存的数据结构中,便于OS进行管理。原创 2023-05-31 19:57:05 · 108 阅读 · 1 评论 -
进程间通信--管道
什么叫管道:由父进程通过调用特定的管道系统调用,以读的方式和写的方式打开一个内存级文件(这个内存级文件是有大小的,也就是说写得过快,写操作会被堵塞,当然,读过快,也会被堵塞到read命令),并通过fork()建立子进程继承下去,分别关闭父子进程的读写端,从而形成一条文件级别的通信信道。如果是文件系统提供的:管道通信,由System V提供的:System V,提供一大块内存:共享内存,如果是计数器:信号量,如果是队列:消息队列。4、读关闭,写:OS会终止写端,给写端发送信号,13,终止写端。原创 2023-05-28 22:25:19 · 105 阅读 · 0 评论 -
Linux基础--进程(二)
其实exit()是c语言封装的函数,其底层是_exit()函数,是一个系统调用,归操作系统调用。当父子进程一起执行的时候,本该是由父进程负责回收子进程的资源,但是父进程率先退出的时候,此时的子进程便会被“寄养”在操作系统名下,此时的进程称之为孤儿进程,但子进程的任务完成之后,又操作系统回收资源,获取子进程退出信息。创建子进程的目的不仅仅在于让子进程执行父进程代码的一部分,可以使用程序替换的方式去让子进程执行一个全新的程序,让子进程加载磁盘上的指定程序,执行新程序的代码和数据,这就是进程替换。原创 2023-05-30 22:26:21 · 58 阅读 · 1 评论 -
Linux基础--进程(一)
对进程的刻板印像:一个程序运行起来,加载到内存之后,就变成一个进程。但从上述而言,操作系统对于计算机资源的管理主要是通过先描述后组织的方式进行管理。所以进程也会以同样的方式被管理。首先从磁盘加载对应的数据和代码进入到内存中,操作系统会生成一个PCB(process control block)对象描述该进程的所有属性和该进程对应的数据和代码,然后通过管理这个PCB链表来达到管理所有的进程目的。//PCB 进程控制块//该进程的所有属性(OS帮你标记的进程属性)//该进程对应的代码和属性。原创 2023-04-26 20:17:46 · 50 阅读 · 1 评论