操作系统

100 阅读10分钟

死锁条件 内核态和用户态的主要区别 进程与线程的区别 ~~线程共享进程哪些资源,独有哪些资源 ~~ 进程与线程 为什么要有进程和线程? 了解死锁吗? 如何避免如何预防 9.线程间的通信方式有哪些? 10.线程间的切换和进程间的切换哪个代价大?

一. 什么是操作系统

  1. 操作系统本质上是一个运行在计算机上的软件程序 ,用于管理计算机硬件和软件资源。
  2. 操作系统的内核(Kernel)是操作系统的核心部分,它负责系统的内存管理,硬件设备的管理,文件系统的管理以及应用程序的管理。
  3. 操作系统存在屏蔽了硬件层的复杂性。

二. 内核态和用户态

  • 进程在系统上的运行分为两个级别:
  1. 用户态(user mode) : 用户态运行的进程可以直接读取用户程序的数据。用户态无法执行受限操作,如 I/O 请求,执行这些操作会引发异常。
  2. 内核态/系统态(kernel mode):可以简单的理解系统态运行的进程或程序几乎可以访问计算机的任何资源,不受限制。核心态只能由操作系统运行,可以执行特权操作。 用户程序通过系统调用 system call 执行这些特权操作。OS 执行前会判断进程是否有权限执行相应的指令。
  3. 什么时候会陷入内核态?--系统调用(trap)、中断(interrupt)和异常(exception)
  • 系统调用,是用户进程主动发起的操作。发起系统调用,陷入内核,由操作系统执行系统调用,然后再返回到进程。
  • 中断和异常是被动的,无法预测发生时机。中断包括 I/O 中断、外部信号中断、各种定时器引起的时钟中断等。异常包括程序运算引起的各种错误如除 0、缓冲区溢出、缺页等。

三. 线程与进程

  1. 对比与定义——线程是进程划分成的更小的运行单位,一个进程在其执行的过程中可以产生多个线程。
  • 进程是程序的一次执行过程,是系统运行程序的基本单位。系统运行一个程序即是一个进程从创建,运行到消亡的过程。
  • 线程:
标题进程线程
资源拥有资源和执行任务的单元体执行任务的单元体,不拥有资源,线程之间共享地址空间
切换开销开销很大开销很小
通信IPC共享内存
健壮性健壮,多个进程之间不会互相干扰不健壮,一个线程出错会终止整个进程
  1. 进程切换--开销很大
  • 处理机的上下文切换:保存和恢复相关寄存器的内容
  • 与进程相关的数据结构更改:存储管理有关的记录信息(如页表)、文件管理有关数据(如文件描述符)、进程控制块中的各种队列(如阻塞队列、就绪队列、通信队列)等
  1. 为何引入线程
  • 进程的处理机资源和其他资源是一起分配的,进程切换的时候会整体切换,开销很大。如果我们只切换必需的、与处理机相关的信息,就可以有效减少开销。由此引入线程:把一个进程分为多个执行任务的单元体,只为其分配处理机,这些执行任务的单元体就是线程。
  1. 线程切换--开销很小
  • 只需要切换处理机执行的上下文,不会改变地址空间
  • 不需要重新加载页表,切换开销少,提高效率
  • 多个线程共享地址空间,有利有弊
  1. 线程共享、独占的资源
1.共享资源
      内存空间
      文件描述符
      信号处理器
      进程ID
2.独占资源
      线程 ID:在本进程中唯一,进程用来标识此线程
      一组寄存器的值
      栈:每个线程中的函数调用过程是独立的,因此需要有独立的栈
      
  1. 线程的5种状态

图片.png 7. 进程的5种状态---大致同上

  • 创建状态(new) :进程正在被创建,尚未到就绪状态。
  • 就绪状态(ready) :进程已处于准备运行状态,即进程获得了除了处理器之外的一切所需资源,一旦得到处理器资源(处理器分配的时间片)即可运行。
  • 运行状态(running) :进程正在处理器上上运行(单核 CPU 下任意时刻只有一个进程处于运行状态)。
  • 阻塞状态(waiting) :又称为等待状态,进程正在等待某一事件而暂停运行如等待某资源为可用或等待 IO 操作完成。即使处理器空闲,该进程也不能运行。
  • 结束状态(terminated) :进程正在从系统中消失。可能是进程正常结束或其他原因中断退出运行。
  1. 进程的通信方式
  • 管道/匿名管道(Pipes) :用于具有亲缘关系的父子进程间或者兄弟进程之间的通信。
  • 有名管道(Names Pipes) : 匿名管道由于没有名字,只能用于亲缘关系的进程间通信。为了克服这个缺点,提出了有名管道。有名管道严格遵循先进先出(first in first out)。有名管道以磁盘文件的方式存在,可以实现本机任意两个进程通信。
  • 信号(Signal) :信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生;
  • 消息队列(Message Queuing) :消息队列是消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识。管道和消息队列的通信数据都是先进先出的原则。与管道(无名管道:只存在于内存中的文件;命名管道:存在于实际的磁盘介质或者文件系统)不同的是消息队列存放在内核中,只有在内核重启(即,操作系统重启)或者显示地删除一个消息队列时,该消息队列才会被真正的删除。消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取.比 FIFO 更有优势。消息队列克服了信号承载信息量少,管道只能承载无格式字 节流以及缓冲区大小受限等缺。
  • 信号量(Semaphores) :信号量是一个计数器,用于多进程对共享数据的访问,信号量的意图在于进程间同步。这种通信方式主要用于解决与同步相关的问题并避免竞争条件。
  • 共享内存(Shared memory) :使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据的更新。这种方式需要依靠某种同步操作,如互斥锁和信号量等。可以说这是最有用的进程间通信方式。
  • 套接字(Sockets) : 此方法主要用于在客户端和服务器之间通过网络进行通信。套接字是支持 TCP/IP 的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程。
  1. 线程间的同步方式:线程同步是两个或多个共享关键资源的线程的并发执行。应该同步线程以避免关键的资源使用冲突。三种方式
  • 互斥量(Mutex):采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个,所以可以保证公共资源不会被多个线程同时访问。比如 Java 中的 synchronized 关键词和各种 Lock 都是这种机制。
  • 信号量(Semphares) :它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量
  • 事件(Event) :Wait/Notify:通过通知操作的方式来保持多线程同步,还可以方便的实现多线程优先级的比较操
  1. 进程的调度算法
  • 先到先服务(FCFS)调度算法
  • 短作业优先(SJF)的调度算法
  • 时间片轮转调度算法
  • 多级反馈队列调度算法:既能使高优先级的作业得到响应又能使短作业(进程)迅速完成。,因而它是目前被公认的一种较好的进程调度算法
  • 优先级调度

四. 死锁

  1. 什么是死锁(其实四个必要条件说的很清楚)
  • 多个进程可以竞争有限数量的资源。当一个进程申请资源时,如果这时没有可用资源,那么这个进程进入等待状态。有时,如果所申请的资源被其他等待进程占有,那么该等待进程有可能再也无法改变状态。这种情况成为死锁。
  1. 产生死锁的四个条件——缺少一个就不会有死锁
  • 互斥:资源必须处于非共享模式
  • 占有并等待:一个进程至少应该占有一个资源,并等待另一资源,而该资源被其他进程所占有。
  • 非抢占:资源不能被抢占,只能等待主动释放
  • 循环等待:每个进程都在等待下一个进程占有的资源
  1. 如何预防死锁——预防死锁就是破坏上面四个条件任意一个,但是实现很难
  • 破坏互斥条件:允许某些资源同时被多个进程访问。但是有些资源本身并不具有这种属性,因此这种方案实用性有限
  • 破坏占有并等待条件: 实行资源预先分配策略(当一个进程开始运行之前,必须一次性向系统申请它所需要的全部资源,否则不运行) 或者只允许进程在没有占用资源的时候才能申请资源(申请资源前先释放占有的资源) 缺点:很多时候无法预知一个进程所需的全部资源;同时,会降低资源利用率,降低系统的并发性
  • 破坏非抢占条件:允许进程强行抢占被其它进程占有的资源。会降低系统性能
  • 破坏循环等待条件:对所有资源统一编号,所有进程对资源的请求必须按照序号递增的顺序提出,即只有占有了编号较小的资源才能申请编号较大的资源。这样避免了占有大号资源的进程去申请小号资源,各个进程申请资源的顺序都是从小到大,就不会有环了
  1. 如何避免死锁
  • 允许系统中同时存在四个必要条件,但是每当进程提出资源申请时,系统要分析满足该资源请求后,系统是否会发生死锁,若不会发生则实施分配,否则拒绝分配。