操作系统_02_进程(个人总结)

    声明: 1. 本文为我的个人复习总结, 并那种从零基础开始普及知识 内容详细全面, 言辞官方的文章
              2. 由于是个人总结, 所以用最精简的话语来写文章
              3. 若有错误不当之处, 请指出

介绍

程序是静态的, 进程是动态的; 运行的程序叫做进程

挂起:

比如read( )引发系统调用使进程阻塞, 此时进程依旧会占用内存空间, 于是操作系统会把阻塞的进程置换到磁盘

  1. 阻塞挂起: 进程在外存(硬盘) 并等待某个事件的出现
  2. 就绪挂起: 进程在外存(硬盘), 并没有在等待某个事件的发生, 只要被换入到内存,就可以立即运行

导致进程挂起的原因:

  1. 进程受到阻塞
  2. 用户希望挂起⼀个程序,比如在 Linux 中用 Ctrl+Z 挂起进程

PCB

PCB 是进程存在的唯一标识,线程的话是TCB,PCB里记录的信息包括:

  1. 进程描述信息

    • 进程标识符:标识各个进程
    • 用户标识符:进程所属的用户
  2. 进程控制和管理信息

    • 进程当前状态
    • 进程优先级
  3. 资源分配清单

    • 内存地址空间或虚拟地址空间的信息
    • 所打开文件的列表和所使用的 I/O 设备信息
  4. CPU 相关信息

    CPU 中各个寄存器的值,当进程被切换时CPU 的状态信息都会被保存在相应的 PCB 中,以便进程重新执行时能从断点处继续执行

PCB通过链表进行组织,相同状态的进程连在一起 组成各种队列; 也可以通过索引表进行组织连接

原语:即原子操作,使用中断指令

进程修改状态:

经过两步, 这两步得是原子操作不可被打断:

  1. 先把这个 PCB 移动到修改后状态所对应的链表 后面,

  2. 再修改 PCB 的进程状态值

进程的控制

  1. 创建进程

    1. 为新进程分配PCB

    2. 为进程分配资源

      如果资源不足,进程就会进入等待状态以等待资源

    3. 初始化 PCB

    4. 如果进程的调度队列能够接纳新进程,那就将进程插入到就绪队列 等待被调度运行

  2. 终止进程

    进程可以有 3 种终止方式:正常结束、异常结束(抛出异常)、外界干预(信号 kill 掉)

    1. 找到进程的 PCB
    2. 如果处于执行状态,则立即终止此进程以及子进程,然后将 CPU 资源分配给其他进程
    3. 将其从 PCB 所在队列中删除
  3. 阻塞进程

    1. 找到进程的 PCB
    2. 如果该进程为运行状态,则保护其现场(保存上下文信息, 比如PC寄存器记录此时程序执行位置), 然后将其状态转为阻塞状态
    3. 将该 PCB 插入到阻塞队列中去
  4. 唤醒进程

    进程⼀旦被阻塞,则它只能由另⼀个进程去唤醒

    1. 找到进程的 PCB
    2. 将其从阻塞队列中移出,并置其状态为就绪状态
    3. 把该 PCB 插入到就绪队列中,等待调度程序调度

总结: 找PCB + 将进程移动至所属队列

进程切换:

发生在何处?

进程是由内核管理和调度的,所以进程的切换只能发生在内核态

切换时发生了什么?

  1. 切换 虚拟内存全局变量 等用户空间的资源,

  2. 切换 内核堆栈寄存器 等内核空间的资源

进程 与 线程 的区别

  1. 进程是操作系统分配资源与调度的基本单位, 线程是cpu进行调度的基本单位

  2. 进程有独立的虚拟地址空间, 而线程没有独立的虚拟地址空间

  3. 进程之间的内存都是独立的, 而线程之间既有独立的栈空间, 又有共享的当前进程的内存空间

  4. 一个进程内可以有多个线程

  5. 进程切换开销大, 而线程切换开销小

    因为 进程切换时 需要切换虚拟地址空间, 而同进程的线程切换时 并不会切换虚拟地址空间

    虚拟地址空间一切换, 页表缓存会失效, 从而虚拟地址转换时会变慢

线程的实现

  1. 用户线程

    对应关系:

    ​ 多对多, 多个用户线程对应一个内核线程

    实现:

    ​ 在用户空间实现的线程,由用户级的线程库来完成线程的管理, 操作系统不直接参与

    优点:

    ​ 无需用户态与内核态的切换, 所以开销小速度快

    缺点:

    ​ 没法打断当前运行中的线程, 故没法实现多线程抢占式调用, 从而并发量低

  2. 内核线程

    对应关系:

    ​ 一对一, 一个用户线程对应一个内核线程

    实现:

    ​ 在内核中实现的线程,是由操作系统内核管理的线程

    优点:

    ​ 可以打断当前运行中的线程, 故可以实现多线程抢占式调用, 从而并发量低

    缺点:

    ​ 经常需要用户态与内核态的切换, 所以开销大速度慢

  3. 轻量级进程

    对应关系:

    ​ 有 多对一,一对一,多对多

    实现:

    ​ 在内核中来支持用户线程

    缺点:

    ​ 经常发生系统调用 切换内核态 与 用户态, 故开销大效率低

    通信:

    每个进程的用户地址空间都是独立的 不能互相访问,但内核空间是每个进程都共享的; 所以进程之间要通信必须通过内核

    1. 管道

      管道传输数据是单向的, 数据先进先出

      实现:

      ​ 管道是内核里的一块缓存, 是特殊的文件,只存在于内存,不存于文件系统中

      ​ ⼀个是管道的读取端描述符 fd[0] ,另⼀个是管道的写入端描述符 fd[1]

      命名管道:

      ​ 适用于任意两个进程之间的通信

      匿名管道:

      ​ 只适用于父子进程之间的通信

      优点:

      ​ 简单

      缺点:

      ​ 管道内的数据必须被读走才能进行继续写入, 通信方式效率低,不适合进程间频繁地交换数据

    2. 消息队列

      管道的升级版, 适合进程间频繁地交换数据, 在消息队列塞满之前 可以不必管数据是否被读取 就可以持续写入数据

      不足之处:

      1. 通信不及时
      2. 附件有大小限制

      管道的生命周期随进程

      消息队列的生命周期随内核

    3. 信号

      发送信号, 如 kill 命令 发送的 SIGKILL 信号
      在这里插入图片描述

    4. 信号量

      是⼀个整型的计数器,主要用于实现进程间的互斥同步

      实现过程:

      有两种原子操作:

      1. P 操作(lock),这个操作会把信号量减去 1
        • 相减后如果信号量 < 0 则表明该资源已被占用,进程需阻塞等待
        • 如果信号量 >= 0,则表明该资源空闲,进程可正常继续执行。
      2. V 操作(unlock),这个操作会把信号量加上 1
        • 相加后如果信号量 <= 0,则表明当前有阻塞中的进程,于是会将该进程唤醒运行
        • 相加后如果信号量 > 0,则表明当前没有阻塞中的进程
    5. 共享内存

      避免了用户态内核态之间的消息拷贝过程

      缺点:

      临界区发生竞态条件 写操作时, 有并发安全问题

    6. Socket

      跨机器的进程通信

      通信方式:

      1. TCP字节流
      2. UDP数据报
      3. 本地进程(实现: 绑定一个本地文件)

    线程:

    线程间的通信可以通过全局变量来实现, 线程不关注通信方式, 而关注多线程间竞争共享资源的问题

    为了解决多线程间竞争共享资源的问题, 引发了同步互斥

    互斥

    保证任意时刻只有⼀个线程访问共享资源, 是多线程之间的竞争

    同步

    保证线程 A 应在线程 B 之前执行, 是多线程间的协调

    死锁

    在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值