目录

  • malloc是如何分配内存
  • 进程的调度方式
    • 进程调度算法
  • CPU调度算法
  • 线程调度
    • 线程调度算法
  • 操作系统如何进行进程管理
  • 磁盘顺序读写与随机读写
  • 操作系统如何工作
  • 操作系统文件管理实现思路
  • Linux下发信号用命令行怎么实现
  • 操作系统创建一个进程的主要步骤主要步骤分为4步:
  • 操作系统基本功能
  • 内核态与用户态的区别
    • 用户态&内核态
  • 操作系统是如何实现锁的?
  • 中断
  • 操作系统中的堆栈

malloc是如何分配内存

  malloc是一个动态分配内存的函数,malloc是在userspace的C库函数,它只是向glibc请求内存空间(虚拟地址空间),相当于glibc帮助进程来管理已经分配的内存地址空间。即glibc持有一定量的属于进程的内存地址空间(注意不是实际的物理内存空间)。主要是初始分配或者通过brk和sbrk或者mmap向内核批发的。

  • 所以malloc首先向glibc查询是否有足够大小的内存空间可用,如果可用,分配返回就好了,malloc函数也就完成了。上面已经说过,真正使用的时候才会产生缺页中断由内核来分配实际的物理内存
  • 如果glibc中管理的本进程的内存地址空间不够分配了,那么malloc将会触发批发操作:brk或者sbrk或者mmap
  • brk、sbrk或者mmap会修改这个进程的内存地址空间相关的信息,相当于进程映射的空间变多了,未开垦的空间又开垦了一些,glibc持有的空间变大了,可以够分配给malloc了,那就分给它就好了
  • 最终上层应用程序中语句开始使用这块分配的内存的时候,触发缺页中断,内核分配物理内存

进程的调度方式

进程的三种状态
1、等待态:等待某个事件的完成;
2、就绪态:等待系统分配处理器以便运行
3、运行态:占有处理器正在运行

三种状态的转化
运行态到等待态:往往是由于等待外设,等待主存等资源分配或等待人工干预而引起的
等待态到就绪态:等待的条件已经满足,只需要分配到处理器后就能运行
就绪态到运行态:系统按某种策略选中就绪队列中的一个进程占用处理器
运行态到就绪态:由于外界原因是运行状态的进程让出处理器,例如有更高优先级的进程来抢占处理器或时间片(时间片是系统分配给程序的运行时间)用完

调度方式
剥夺方式:当一个进程正在运行时,系统可以基于某种原则,剥夺已分配给他的处理机,将之分配给其他进程,剥夺原则有:优先权原则、短进程优先原则、时间片原则
非剥夺方式:分配程序一旦把处理机分配给某进程后便让它一直运行下去,直到进程完成或发生事件而阻塞时,才把处理机分配给另一个进程

进程调度算法

1、先来先服务调度算法(FCFS,first come first served):谁第一个排队,谁就先被执行,在它执行过程中,不会中断它

2、短进程优先调度算法(SPF,shortest process first):对预计执行时间短的进程优先分配处理机,通常后来的短进程不会抢先正在执行的进程;对长进程非常不利,可能长时间得不到执行

3、最高响应比优先调度算法(HRRN,highest response radio next):在批处理系统中,短作业优先算法是一种比较好的算法,其主要的不足之处是长作业的运行得不到保证。HRRN为每个作业引入前面所述的动态优先权,并使作业的优先级随着等待时间的增加而以速率a 提高,则长作业在等待一定的时间后,必然有机会分配到处理机。该优先权的变化规律可描述为:

优点:长作业也有机会投入运行,缺点:每次调度前要计算响应比,会增加系统开销。

4、时间片轮转法(RR,Round-Robin):采用剥夺方式,每个进程被分配一个时间段,按照在队列中的顺序交替执行;不利于处理紧急作业。系统将所有的就绪进程按先来先服务的原则排成一个队列,每次调度时,把CPU分配给队首进程,并令其执行一个时间片。当执行的时间片用完时,由一个计时器发出时钟中断请求,调度程序便据此信号来停止该进程的执行,并将它送往就绪队列的末尾;然后,再把处理机分配给就绪队列中新的队首进程,同时也让它执行一个时间片。这样就可以保证系统能在给定的时间内响应所有用户的请求。

5、多级反馈队列算法(multilevel feedback queue): UNIX使用这种调度算法;进程在进入待调度的队列等待时,首先进入优先级最高的Q1中等待;首先调度优先级高的队列中的进程。若高优先级队列中已经没有调度的进程,则调度次优先级队列的进程;同一队列中的各个进程按照时间片轮转调度;在低优先级队列中的进程在运行时,又有新到达的作业,那么在运行完这个时间片后,CPU马上分配给新到达的作业(剥夺)。

(1) 应设置多个就绪队列,并为各个队列赋予不同的优先级。第一个队列的优先级最高,第二个队列次之,其余各队列的优先权逐个降低。该算法赋予各个队列中进程执行时间片的大小也各不相同,在优先权愈高的队列中,为每个进程所规定的执行时间片就愈小。例如,第二个队列的时间片要比第一个队列的时间片长一倍,……,第i+1个队列的时间片要比第i个队列的时间片长一倍。

(2)当一个新进程进入内存后,首先将它放入第一队列的末尾,按FCFS原则排队等待调度。当轮到该进程执行时,如它能在该时间片内完成,便可准备撤离系统;如果它在一个时间片结束时尚未完成,调度程序便将该进程转入第二队列的末尾,再同样地按FCFS原则等待调度执行;如果它在第二队列中运行一个时间片后仍未完成,再依次将它放入第三队列,……,如此下去,当一个长作业(进程)从第一队列依次降到第n队列后,在第n 队列便采取按时间片轮转的方式运行。

(3) 仅当第一队列空闲时,调度程序才调度第二队列中的进程运行;仅当第1~(i-1)队列均空时,才会调度第i队列中的进程运行。如果处理机正在第i队列中为某进程服务时,又有新进程进入优先权较高的队列(第1~(i-1)中的任何一个队列),则此时新进程将抢占正在运行进程的处理机,即由调度程序把正在运行的进程放回到第i队列的末尾,把处理机分配给新到的高优先权进程。

6、高优先权优先调度算法:为了照顾紧迫型作业,使之在进入系统后便获得优先处理,引入了最高优先权优先(FPF)调度算法。此算法常被用于批处理系统中,作为作业调度算法,也作为多种操作系统中的进程调度算法,还可用于实时系统中。当把该算法用于作业调度时,系统将从后备队列中选择若干个优先权最高的作业装入内存。当用于进程调度时,该算法是把处理机分配给就绪队列中优先权最高的进程,这时,又可进一步把该算法分成如下两种。
3.1) 非抢占式优先权算法:在这种方式下,系统一旦把处理机分配给就绪队列中优先权最高的进程后,该进程便一直执行下去,直至完成;或因发生某事件使该进程放弃处理机时,系统方可再将处理机重新分配给另一优先权最高的进程。这种调度算法主要用于批处理系统中;也可用于某些对实时性要求不严的实时系统中。
3.2) 抢占式优先权调度算法:在这种方式下,系统同样是把处理机分配给优先权最高的进程,使之执行。但在其执行期间,只要又出现了另一个其优先权更高的进程,进程调度程序就立即停止当前进程(原优先权最高的进程)的执行,重新将处理机分配给新到的优先权最高的进程。因此,在采用这种调度算法时,是每当系统中出现一个新的就绪进程i 时,就将其优先权Pi与正在执行的进程j 的优先权Pj进行比较。如果Pi≤Pj,原进程Pj便继续执行;但如果是Pi>Pj,则立即停止Pj的执行,做进程切换,使i 进程投入执行。显然,这种抢占式的优先权调度算法能更好地满足紧迫作业的要求,故而常用于要求比较严格的实时系统中,以及对性能要求较高的批处理和分时系统中。
3.3)容易出现优先级倒置现象:优先级反转是指一个低优先级的任务持有一个被高优先级任务所需要的共享资源。高优先任务由于因资源缺乏而处于受阻状态,一直等到低优先级任务释放资源为止。而低优先级获得的CPU时间少,如果此时有优先级处于两者之间的任务,并且不需要那个共享资源,则该中优先级的任务反而超过这两个任务而获得CPU时间。如果高优先级等待资源时不是阻塞等待,而是忙循环,则可能永远无法获得资源,因为此时低优先级进程无法与高优先级进程争夺CPU时间,从而无法执行,进而无法释放资源,造成的后果就是高优先级任务无法获得资源而继续推进。
3.4)优先级反转案例解释:不同优先级线程对共享资源的访问的同步机制。优先级为高和低的线程tall和线程low需要访问共享资源,优先级为中等的线程mid不访问该共享资源。当low正在访问共享资源时,tall等待该共享资源的互斥锁,但是此时low被mid抢先了,导致mid运行tall阻塞。即优先级低的线程mid运行,优先级高的tall被阻塞。
3.5)优先级倒置解决方案:
(3.5.1)设置优先级上限,给临界区一个高优先级,进入临界区的进程都将获得这个高优先级,如果其他试图进入临界区的进程的优先级都低于这个高优先级,那么优先级反转就不会发生。
(3.5.2)优先级继承,当一个高优先级进程等待一个低优先级进程持有的资源时,低优先级进程将暂时获得高优先级进程的优先级别,在释放共享资源后,低优先级进程回到原来的优先级别。嵌入式系统VxWorks就是采用这种策略。
(3.5.3)第三种方法就是临界区禁止中断,通过禁止中断来保护临界区,采用此种策略的系统只有两种优先级:可抢占优先级和中断禁止优先级。前者为一般进程运行时的优先级,后者为运行于临界区的优先级。火星探路者正是由于在临界区中运行的气象任务被中断发生的通信任务所抢占才导致故障,如果有临界区的禁止中断保护,此一问题也不会发生。

CPU调度算法

批处理系统中采用的调度算法

  • 非抢占式的先来先服务算法(FCFS):按照进程就绪的先后顺序使用CPU。特点:公平,实现简单,但是长进程后面的短进程需要等待很长时间,不利于用户体验
  • 非抢占式的最短作业优先(SJF):具有最短完成时间的进程优先执行
  • 最短剩余时间优先(SRTN):SJF抢占式版本,即当一个新就绪的进程比当前运行进程具有更短完成时间时,系统抢占当前进程,选择新就绪的进程执行。短作业优先调度算法特点:改善短作业的周转时间,但如果源源不断有短任务到来,可能使长的任务长时间得不到运行,产生饥饿现象
  • 最高响应比优先算法(HRRN):是一个综合算法,调度时,首先计算每个进程的响应比R,之后总是选择R最高的进程执行。响应比R=(等待时间+处理时间)/处理时间

交互系统中采用的调度算法

  • 时间片轮转调度算法: 每个进程被分配一个时间片,允许该进程在该时间段运行,如果在时间片结束时该进程还在运行,则剥夺CPU并分配给另一个进程,如果该进程在时间片结束前阻塞或结束,则CPU立即进行切换。当时间片选择太长,其降级为先来先服务算法,引起对短的交互请求响应时间长。当时间片选择太短,会导致频繁的进程切换,浪费CPU时间。通常选择为20ms~50ms。对进程表中不同进程的大小差异较大的有利,而对进程都是相同大小的不利。
  • 虚拟轮转法:主要基于时间片轮转法进行改进,解决在CPU调度中对于I/O密集型进程的不友好。其设置了一个辅助队列,对于I/O型进程执行完一个时间片之后,则进入辅助队列,CPU调度时总是先检查辅助队列是否为空,如果不为空总是优先调度辅助队列里的进程,直到为空,才调度就绪队列的进程。
  • 最高优先级调度算法:选择优先级最高的进程优先执行。优先级可以静态不变,也可以动态调整。优先数决定优先级。就绪队列可以按照优先级组织。实现简单,但不公平,可能导致优先级低的进程产生饥饿现象。可能产生优先级反转问题(基于优先级的抢占式算法),即一个低优先级进程持有一个高优先级进程所需要的资源,使得高优先级进程等待低优先级进程运行。
  • 多级反馈队列调度算法:设置多个就绪队列,并为各个队列赋予不同的优先级。第一个队列的优先级最高,依次递减优先级。对于各个队列进程执行时间片的大小也不同,优先级越高的队列,分配到的时间片越少。当第一级队列为空时,再第二级队列进行调度,依次类推,各级队列按照时间片轮转方式进行调度。当一个新进程创建后,首先把它放入第一队列的末尾。按照FCFS原则排队等待调度。当轮到该进程执行时,如它在该时间片完成,便可准备撤离系统,如果它在一个时间片结束时尚未完成,则调度程序便将该进程转入第二队列的末尾,再同样地按照FCFS原则等待调度执行。依次类推。

线程调度

  计算机通常只有一个cpu,在任意时刻只能执行一条机器指令,每个线程只有获得cpu的使用权才能执行指令。所谓多线程的并发运行,其实是从宏观上看,各个线程轮流获取cpu的使用权,分别执行各自的任务。在运行池中,会有多个处于就绪状态的线程在等待cpu,JAVA虚拟机的一项任务就是负责线程的调度。线程调度是指按照特定机制为多个线程分配CPU的使用。线程有两种调度模型:
1、分时调度模型:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用CPU的时间片。
2、抢占式调度模型:JAVA虚拟机采用抢占式调度模式,是指优先让可运行池中优先级高的线程占用CPU,如果可运行池中的线程优先级相同,那就随机选择一个线程,使其占用CPU.处于运行状态的线程会一直运行,直至它不得不放弃CPU。

线程调度算法

1、先进先出算法(FIFO,First-In-First-Out)
  按照任务进入队列的顺序,依次调用,执行完一个任务再执行下一个任务,只有当任务结束后才会发生切换。
优点:

  • 最少的任务切换开销(因为没有在任务执行过程中发生切换,故任务切换开销为0)
  • 最大的吞吐量(因没有任务切换开销,在其他一定的情况下,吞吐量肯定是最大的)
  • 最朴实的公平性(先来先做)

缺点:
  平均响应时间高:耗时只需10毫秒的任务若恰巧在耗时1000毫秒的任务后到来,他则需要1010毫秒才能执行完成,绝大部分时间都花在等待被调度了。
适用场景:队列中任务的耗时差不多的场景。

2、最短耗时任务优先算法
  按照任务的耗时长短进行调度,优先调度耗时短的任务,这个算法有个前提,需要预先知道每个任务的耗时情况,这在实际情况中是不大现实的。另外,这个时间是指任务剩余还需要的执行时间,举例,一个耗时1小时的任务还剩10秒执行完成,这个时候若再来一个耗时1分钟的任务,调度仍然还是继续执行完那个耗时1小时的任务,因为他剩余的时间是10秒,比1分钟短,所以此算法又叫最短剩余时间任务有限算法(SRTJ),能够解决FIFO算法中短耗时任务等待前面耗时长任务的窘境。
优点:平均响应时间较低:这里有一点,因为将时间长的任务无限往后推移,实际计算的平均响应时间的任务都是执行较快的任务,统计出来的平均响应时间必然较低的。
缺点:

  • 耗时长的任务迟迟得不到调度,不公平,容易形成饥饿
  • 频繁的任务切换,调度的额外开销大

适用场景:几乎无适用场景。

3、时间片轮转算法(Round Robin)
  给队列中的每个任务一个时间片,第一个任务先执行,时间片到了之后,将此任务放到队列尾部,切换到下个任务执行,这样能解决SJF中耗时长任务饥饿的问题。算法介于FIFO和SJF之间,若时间片足够大,则退化到FIFO,若分片足够小(假设不考虑任务切换的开销),则任务的完成时间顺序是以耗时从小到大排列(相比SFJ,任务执行的绝对时间会长,取决于队列中任务的个数)。

优点:

  • 每个任务都能够得到公平的调度
  • 耗时短的任务即使落在耗时长的任务后面,也能够较快的得到调度执行

缺点:

  • 任务切换引起的调度开销较大,需要多次切换任务上下文
  • 时间片不太好设置(若设置短了,调度开销大,若设置长了,极端情况是退化到FIFO)

适用场景:队列中耗时差不多的任务(比如,多路视频流处理)
不适用场景:计算型任务和I/O型任务混合的队列

4、最大最小公平算法( Max-Min Fairness )
  ,此算法是为了保证公平性,最初源自通信网络的带宽分配与控制场景。

操作系统如何进行进程管理

  进程控制是通过原语实现的,原语也称为原子操作。原语采用“关中断指令”和“开中断指令”实现不可中断的特性。原语代码放入关、开中断指令之间运行时,外部中断信号不能使其停止运行,只有当其中的指令运行结束后,外部中断指令才可以使程序中断运行。
原语要做的三类事情:
1、更新PCB中的信息(如修改进程状态标志、将运行环境保存到PCB、从PCB恢复运行环境)。
2、将PCB插入合适的队列。
3、分配/回收资源。

创建原语(无 —> 创建态 —> 就绪态):
1、申请空白PCB。
2、为新进程分配所需资源。
3、初始化PCB。
4、将PCB插入继续队列。

撤销原语(就绪态/阻塞态/运行态 —> 终止态 —> 无):
1、从PCB集合中找到终止的PCB。
2、若进程正在运行,立即剥夺CPU,将CPU分配给其他进程。
3、终止其所有子进程。
4、将该进程拥有的所有资源归还给父进程或操作系统。
5、撤销PCB。

阻塞原语(运行态 —> 阻塞态):
1、找到要阻塞进程对应的PCB。
2、保护进程运行现场,将PCB状态信息设置为“阻塞态”,暂时停止进程运行。
3、将PCB插入相应事件的等待队列。

唤醒原语(阻塞态 —> 就绪态):
1、在事件等待队列中找到PCB。
2、将PCB从等待队列移除,设置进程为就绪态。
3、将PCB插入就绪队列,等待被调度。

切换原语(运行态 —> 阻塞态/就绪态;就绪态 —> 运行态):
1、将运行环境信息存入PCB。
2、PCB移入相应的队列。
3、选择另一个进程执行,并更新其PCB。
4、根据PCB恢复新进程所需的运行环境。

磁盘顺序读写与随机读写

  只有顺序写才能保证顺序读。当读取第一个block时,要经历寻道,旋转延迟,传输三个步骤才能读取完这个block的数据.而对于下一个block,如果它在磁盘的某个位置,访问它会同样经历寻道,旋转,延时,传输才能读取完这个block的数据, 我们把这种方式的IO叫做随机IO.但是如果这个block的起始扇区刚好在我刚才访问的block的后面,磁头就能立刻遇到.不需等待,直接传输.这种IO就叫顺序IO.

操作系统如何工作

  OPS在体系结构上主要由以下特点:以运算单元为中心、采用存储程序原理、存储器按地址访问、线性编址空间、控制流由指令流产生、指令由操作码和地址码组成、数据以二进制进行编码。

堆栈机制:堆是由程序员自己分配的,需自己释放的。栈是由编译器自动分配和释放的一段内存,主要用来传递参数、保存寄存器的值,保存上下文切换现场。

中断机制:中断是CPU提供的允许其他模块打断处理器正常处理过程的机制。常见的中断类别有:程序中断、时钟中断、IO中断、硬件故障中断

操作系统(内核)是如何工作
  当一个进程在执行一个程序的时候,进来一个中断,CPU首先将当前EIP,ESP压入内核 栈,然后把ESP指向内核栈,EIP指向中断处理的入口,其中最关键的就是TSS,因为TSS中保存了用户态下各个寄存器的信息,所以将用户态下的EIP 和ESP入栈,就相当于对进程之前的一个状态进行保存,以便于从中断返回后继续执行之前任务,然后kernel调用SAVE_ALL来将其他寄存器信息保 存在栈中,接着根据CS EIP指向的中断程序,对中断进行处理。当执行完一个中断后,会通过schedule进行调度,其中最重要的要数switch_to,其会调用 _switch_to函数来进行调度。当中断执行完后,若要返回到用户态,就需要回到最初中断开始的地方继续执行先前任务,这就需要 restore_all将之前保存在内核栈中的值出栈,然后通过iret恢复其计算器的状态,这样我们就又回到了用户态,继续执行之前因中断而暂停的任务。
  操作系统工作的核心概念是进程,进程是程序的动态执行。大部分的操作系统都有自己的核心进程,系统启动完成最后的操作就是启动核心进程,然后其他的所有执行程序其实都是这个进程的子子孙孙,而这个核心进程可以控制子子孙孙间同步执行和进程切换以及终止子进程。最后一旦这个核心进程也挂了,或是执行完就是操作系统关闭了。切换的流程如下:
(1)将当前的用户态堆栈的esp、ebp指针保存在当前进程内核栈
(2)执行SAVE_ALL,保存进程a的各个寄存器的值到其内核栈中;
(3)进入中断处理程序;
(4)操作系统调用schedule()函数来进行进程调度,进入进程b的内核栈;
(5)执行RESTALL_ALL,恢复现场,恢复进程b的寄存器的值;
(6)执行IRET,恢复EIP、ESP以及EFLAGS寄存器;
(7)系统从内核态返回到用户态。

操作系统文件管理实现思路

文件管理具有对文件存储空间的管理、目录管理、文件的读/写管理以及文件的共享与保护功能

文件存储空间的管理:
空闲磁盘分区管理:
  成组链接法(管理空闲磁盘分区)数据结构:栈、链表。成组链接法是UNIX/Linux等大型文件系统采用的文件空间管理方法。在UNIX/Linux系统中,将空闲块分成若干组,每100个空闲块为一组,每组的第一个空闲块登记了下一组空闲块的物理盘块号和空闲块总数。如果一组的第一个空闲块号等于0,则有特殊的含义,意味着该组是最后一组,即无下一个空闲块。平时整个链接信息保存于计算机系统磁盘上的系统区,系统启动以后,第一组的链接信息经缓冲区复制到内存专用块中。

具体文件管理:
链接分配:链接文件(将一个文件离散的进行存储,存储信息存储在FAT表中,FAT存储在FCB中)。所有链接指针统一存放在一张显示的链接表(fat表:文件分配表)中。一个逻辑磁盘设置一张表,以物理盘块号为序,表项内容为指向某文件的下一盘块的指针。

文件存取\修改方法:
文件读取就通过文件目录读取(流程:文件目录 -> FCB ->FAT->合并)。删除文件和添加文件都要修改空闲盘块栈。

目录管理:
  多级目录,其中第一级对应于用户账号,第二级对应于用户账号下的文件,第三级对应文件夹下的文件。主目录和子目录都以文件的形式存放于磁盘,这样便于查找和修改。目录文件的每个目录项存放文件名和FCB

Linux下发信号用命令行怎么实现

  信号是Linux系统响应某些条件而产生的一个事件,接收该信号的进程会响应地采取一些行动。signal 定义:在进程控制块 (PCB Process Control Block) 的数据结构中,存在一个信号定义的 Bit Map,还有与其对应的信号处理函数 (handler)
信号处理
signal.h 是 C 标准函数库中的信号处理部分,通过调用 signal() 函数,可以自定义程序执行中触发信号的行为

发送信号
使用 signal.h 中的 kill() 函数是用来给指定进程发送信号

操作系统创建一个进程的主要步骤主要步骤分为4步:

1、申请空白PCB(过程控制块)
2、为新工序分配资源
3、初始化PCB
4、将新进程插入就绪队列

操作系统基本功能

  • 进程管理:进程控制、进程同步、进程通信、死锁处理、处理机调度等
  • 内存管理:内存分配、地址映射、内存保护与共享、虚拟内存等
  • 文件管理:文件存储空间的管理、目录管理、文件读写管理和保护等
  • 设备管理:完成用户的 I/O 请求,方便用户使用各种设备,并提高设备的利用率。主要包括缓冲管理、设备分配、设备处理、虛拟设备等

内核态与用户态的区别

  当一个任务(进程)执行系统调用而陷入内核代码中执行时,就称进程处于内核运行态(简称为内核态)。此时处理器处于特权级最高的(0级)内核代码中执行。当进程处于内核态时,执行的内核代码会使用当前进程的内核栈。每个进程都有自己的内核栈。当进程在执行用户自己的代码时,则称其处于用户运行态(用户态)。即此时处理器在特权级最低的(3级)用户代码中运行。当正在执行用户程序而突然被中断程序中断时,此时用户程序也可以象征性地称为处于进程的内核态。因为中断处理程序将使用当前进程的内核栈。这与处于内核态的进程的状态有些类似。
  从特权级的调度来理解用户态和内核态的区别,当程序运行在3级特权级上时,就称之为运行在用户态,因为这是最低特权级,是普通的用户进程运行的特权级,大部分用户直接面对的程序都是运行在用户态;反之,当程序运行在0级特权级上时,就可以称之为运行在内核态。运行在用户态下的程序不能直接访问操作系统内核数据结构和程序。

用户态和内核态的转换:
用户态—>内核态:唯一途径是通过中断、异常、陷入机制(访管指令)
a. 系统调用
这是用户态进程主动要求切换到内核态的一种方式,用户态进程通过系统调用申请使用操作系统提供的服务程序完成工作
b. 异常
  当CPU在执行运行在用户态下的程序时,发生了某些事先不可知的异常,这时会触发由当前运行进程切换到处理此异常的内核相关程序中,也就转到了内核态,比如缺页异常。
c. 外围设备的中断
  当外围设备完成用户请求的操作后,会向CPU发出相应的中断信号,这时CPU会暂停执行下一条即将要执行的指令转而去执行与中断信号对应的处理程序,如果先前执行的指令是用户态下的程序,那么这个转换的过程自然也就发生了由用户态到内核态的切换。比如硬盘读写操作完成,系统会切换到硬盘读写的中断处理程序中执行后续操作等。

内核态—>用户态:设置程序状态字PSW

用户态&内核态

用户态:用户态运行的进程可以直接读取用户程序的数据
内核态:内核态运行的进程或程序几乎可以访问计算机的任何资源,不受限制
两者最重要的差别就在于特权级的不同,即权力的不同。运行在用户态下的程序不能直接访问操作系统内核数据结构和程序。当我们在系统中执行一个程序时,大部分时间是运行在用户态下的,在其需要操作系统帮助完成某些它没有权力和能力完成的工作时就会切换到内核态
用户态切换到内核态的3种方式:
系统调用:这是用户态进程主动要求切换到内核态的一种方式,用户态进程通过系统调用申请使用操作系统提供的服务程序完成工作。而系统调用的机制其核心还是使用了操作系统为用户特别开放的一个中断来实现
异常:当CPU在执行运行在用户态下的程序时,发生了某些事先不可知的异常,这时会触发由当前运行进程切换到处理此异常的内核相关程序中,也就转到了内核态,比如缺页异常
外围设备的中断:当外围设备完成用户请求的操作后,会向CPU发出相应的中断信号,这时CPU会暂停执行下一条即将要执行的指令转而去执行与中断信号对应的处理程序,如果先前执行的指令是用户态下的程序,那么这个转换的过程自然也就发生了由用户态到内核态的切换。(比如硬盘读写操作完成,系统会切换到硬盘读写的中断处理程序中执行后续操作等。)

操作系统是如何实现锁的?

  在硬件层面,CPU提供了原子操作、关中断、锁内存总线的机制;OS基于这几个CPU硬件机制,就能够实现锁;再基于锁,就能够实现各种各样的同步机制(信号量、消息、Barrier等)。通过锁机制,能够保证在多核多线程环境中,在某一个时间点上,只能有一个线程进入临界区代码,从而保证临界区中操作数据的一致性。锁机制的同步原语都是原子操作,操作系统之所以能构建锁之类的同步原语,是因为硬件已经提供了一些原子操作,例如:中断禁止和启用、内存加载和存入测试与设置指令。

操作系统中的锁机制
互斥锁:mutex,用于保证在任何时刻,都只能有一个线程访问该对象。只有取得互斥锁的进程才能进入临界区,无论读写,当获取锁操作失败时,线程会进入睡眠,等待锁释放时被唤醒
读写锁:rwlock,分为读锁和写锁。读写锁要根据进程进入临界区的具体行为(读,写)来决定锁的占用情况。这样锁的状态就有三种了:读加锁、写加锁、无锁。
无锁。读/写进程都可以进入;
读锁。读进程可以进入。写进程不可以进入;
写锁。读/写进程都不可以进入
自旋锁:spinlock,自旋锁是指在进程试图取得锁失败的时候选择忙等待而不是阻塞自己。
选择忙等待的优点在于如果该进程在其自身的CPU时间片内拿到锁(说明锁占用时间都比较短),则相比阻塞少了上下文切换
注意这里还有一个隐藏条件:多处理器。因为单个处理器的情况下,由于当前自旋进程占用着CPU,持有锁的进程只有等待自旋进程耗尽CPU时间才有机会执行,这样CPU就空转了
RCU:read-copy-update,在修改数据时,首先需要读取数据,然后生成一个副本,对副本进行修改,修改完成后,再将老数据update成新的数据。【有点像 copy-on-write】
使用RCU时,读者几乎不需要同步开销,既不需要获得锁,也不使用原子指令,不会导致锁竞争,因此就不用考虑死锁问题了。
对于写者的同步开销较大,它需要复制被修改的数据,还必须使用锁机制同步并行其它写者的修改操作。
在有大量读操作,少量写操作的情况下效率非常高。【读多写少】

中断

  早期计算机各个程序只能串行执行、系统资源利用低。为了解决上述问题,操作系统引入了中断机制,实现了多道程序的并发执行,提高了系统资源的利用率。中断是多程序并发执行的前提条件,当一个时间片运行完后,CPU会接收到计时部件(操作系统内核的时钟管理部件)发出的中断信号,CPU立即进入核心态,把CPU的使用权限交还给操作系统。当中断发生后,当前运行的进程暂停运行,操作系统内核对中断进程处理,切换进程(根据进程调度算法),在完成切换进程的一系列工作后,操作系统又会将CPU的使用权交还给用户进程。切换到的进程2拿到CPU执行权就会在用户态下执行

中断的处理过程
1、执行完每个指令后,CPU都要检查当前是否有外部中断信号
2、如果检测到外部中断信号,则需要保护被中断进程的CPU环境(如程序状态字PSW、程序计数器、各种通用寄存器)
3、根据中断信号类型转入相应的中断处理程序
4、恢复进程的CPU环境并退出中断,返回原进程继续往下执行

缺页中断
  在请求分页系统中,可以通过查询页表中的状态位来确定所要访问的页面是否存在于内存中。每当所要访问的页面不在内存是,会产生一次缺页中断,此时操作系统会根据页表中的外存地址在外存中找到所缺的一页,将其调入内存。缺页本身是一种中断,与一般的中断一样,需要经过4个处理步骤:保护CPU现场、分析中断原因、转入缺页中断处理程序进行处理、恢复CPU现场,继续执行。但是缺页中断是由于所要访问的页面不存在于内存时,由硬件所产生的一种特殊的中断,因此,与一般的中断存在区别:
1、在指令执行期间产生和处理缺页中断信号
2、一条指令在执行期间,可能产生多次缺页中断
3、缺页中断返回的是,执行产生中断的一条指令,而一般的中断返回的是,执行下一条指令

操作系统中的堆栈

  栈存储函数内部(包括main函数)的局部变量,方法调用及函数参数值,由编译器/系统自动分配和释放。栈存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈,满足:“先进后出”的原则存取。栈是由系统自动分配的,一般速度较快。栈是向低地址扩展的,是一块连续的内存的区域。栈顶的地址和栈的最大容量是系统预先规定好的。
  堆被程序申请使用的内存在被主动释放前一直有效。堆需要由由程序员手动释放,不及时回收容易产生内存泄露。 程序结束时可能由操作系统回收。栈是存放在一级缓存中的,而堆则是存放在二级缓存中的,堆的生命周期由虚拟机的垃圾回收算法来决定,所以调用这些对象的速度要相对来得低一些,故堆的速度慢于栈的速度。与数据结构中的堆是不同的,分配方式类似于链表(空闲链表法),堆是向高地址扩展的数据结构,是不连续的内存区域,这是由于系统是用链表来存储空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。

OPS and So on.相关推荐

  1. 在cuDNN中简化Tensor Ops

    在cuDNN中简化Tensor Ops 在Tesla V100 GPU中引入神经网络模型以来,神经网络模型已迅速利用NVIDIA Tensor Cores进行深度学习.例如,基于Tensor Core ...

  2. 从Ops到NoOps,阿里文娱智能运维的关键:自动化应用容量管理

    作者|  阿里文娱高级开发工程师 金呈 编辑 | 夕颜 来源 | CSDN(ID:CSDNnews) 概述 1. 背景 随着业务形态发展,更多的生产力集中到业务创新,这背后要求研发能力的不断升级.阿里 ...

  3. Dubbo OPS工具——dubbo-admin dubbo-monitor

    1. 前言 今年八月份的时候,查看github仓库,Dubbo OPS还提供了三种工具用于Dubbo的监控运维: 九月份,伴随着Dubbo的全面快速的升级,现在仓库里Dubbo OPS下这三个工具已经 ...

  4. ‘mmdet\ops\nms\src/soft_nms_cpu.pyx‘ doesn‘t match any files

    'mmdet\ops\nms\src/soft_nms_cpu.pyx' doesn't match any files 试试? pip install mmdet 自动安装mmcv win10上可以 ...

  5. Can't get source for site-packages\torchvision\ops\poolers.py. TorchScript requires source access in

    Can't get source for site-packages\torchvision\ops\poolers.py. TorchScript requires source access in ...

  6. 沪江基于容器编排的Dev/Ops流程

    [编者的话]我们整个 DevOps 流程是建立在容器编排的基础上的,目的是简化流程和实现自动化 CI/CD 和自动化运维.当中会有很多没有想到的地方,可能也不太适用于复杂场景. 本文讲的是沪江基于容器 ...

  7. DevOps笔记-05:IT行业中BA、SM、PO、PM、PD、Dev、Ops、QA都是什么角色

    1.BA (1)定义 BA是Business Analys缩写,即业务需求分析师.在互联网公司里,BA的角色就是产品经(PM),只是BA要承接某个很具体的业务或者领域,比如银行也有自己的IT部门,银行 ...

  8. 成功解决ModuleNotFoundError: No module named 'torchvision.ops'

    成功解决ModuleNotFoundError: No module named 'torchvision.ops 目录 解决问题 解决方法 解决问题 Traceback (most recent c ...

  9. 成功解决AttributeError: module 'tensorflow.python.ops.nn' has no attribute '_seq2seq'

    成功解决AttributeError: module 'tensorflow.python.ops.nn' has no attribute '_seq2seq' 目录 解决问题 解决思路 解决方法 ...

  10. 成功解决softmax_cross_entropy_with_logits (from tensorflow.python.ops.nn_ops) is deprecated and will be

    成功解决softmax_cross_entropy_with_logits (from tensorflow.python.ops.nn_ops) is deprecated and will be ...

最新文章

  1. 春运背后默默守护高铁安全的“隐形人”
  2. python爬虫实战(一)~爬取百度百科人物的文本+图片信息+Restful api接口
  3. 集成电路883和883b有什么区别
  4. 同步与异步系列之二 导读目录
  5. Esxi直通板载Sata
  6. 计算机视觉论文-2021-06-30
  7. Linux下进程的建立 并附Linux exec函数族
  8. Kafka常用命令之kafka-console-consumer.sh
  9. Zookeeper的Leader选举
  10. 全国大学生数学建模竞赛历年赛题及优秀论文(链接见ping论)
  11. STM8L152的LCD模块原理及驱动
  12. Docker概述(一)(标贝科技)
  13. 第二次作业:软件人才社会需求现状及发展趋势分析
  14. 2020仙气十足的女生个性网名
  15. 佐切的第三天学习分享
  16. tplink怎么进去_如何进入tp-link无线路由器设置界面
  17. 重写equals方法一定要重写hashcode方法吗
  18. 护眼色的RGB值 和 颜色代码
  19. 我的中软国际实习Day16
  20. ANSI编码文件批量转换为UTF-8编码小tips

热门文章

  1. NXP JN5169使用EEPROM/片上FLASH/随机数/内部NVM
  2. 应用ceph对象存储(ceph-13.2.10)
  3. 后端接收Get请求与Post请求 参数示例
  4. airsim--client
  5. 【TS】<T> 泛型
  6. 以下是一些常用的上位机开发工具:
  7. 2021贵港市地区高考成绩排名查询,贵港高中成绩排名2021,贵港中考分数线排行榜...
  8. MySQL之Xtrabackup备份与恢复
  9. Sublime出现错误——“plugin_host has existed unexpectedly......”
  10. 场效应晶体管有什么特点