zoukankan      html  css  js  c++  java
  • 进程切换和线程切换?

    我们都知道线程切换的开销比进程切换的开销小,那么小在什么地方?切换的过程是怎样的?

    无论是在多核还是单核系统中,一个CPU看上去都像是在并发的执行多个进程,这是通过处理器在进程间切换来实现的。

    • 操作系统实现这种交错执行的机制称为上下文切换。
    • 操作系统保持跟踪进程运行所需的所有状态信息,这种状态,也就是上下文,它包括许多信息,例如PC和寄存器文件的当前值,以及主存的内容。

    在任何一个时刻,单处理器系统都只能执行一个进程的代码。

    当操作系统决定要把控制权从当前进程转移到某个新进程时,就会进行上下文切换,即保存当前进程的上下文,恢复新进程的上下文,然后将控制权传递到新进程,新进程就会从上次停止的地方开始

    深入计算机系统一书中对上下文切换的表达如下图:

      如果现在有两个并发的进程:外壳进程和hello进程。
      开始只有外壳进程在运行,即等待命令行上的输入,当我们让他运行hello程序时,外壳通过调用一个专门的函数,即系统调用,来执行我们的请求,系统调用会将控制权传递给操作系统。
      操作系统保存外壳进程的上下文,创建一个新的hello进程及其上下文,然后将控制权传递给新的hello进程。
      hello进程终止后,操作系统恢复外壳进程的上下文,并将控制权传回给他,外壳进程将继续等待下一个命令行输入。

    上下文切换

    内核为每一个进程维持一个上下文。上下文就是内核重新启动一个被抢占的进程所需的状态。包括一下内容:

    • 通用目的寄存器
    • 浮点寄存器
    • 程序计数器
    • 用户栈
    • 状态寄存器
    • 内核栈
    • 各种内核数据结构:比如描绘地址空间的页表,包含有关当前进程信息的进程表,以及包含进程已打开文件的信息的文件表。

    进程切换

    系统中的每个程序都是运行在某个进程的上下文中的。
      上下文是由程序正确运行所需的状态组成的,这个状态包括存放在存储器中的程序的代码和数据,他的栈,通用目的寄存器的内容,程序计数器,环境变量以及打开文件描述符的集合

    所以进程切换就是上下文切换。

     那回到最开始的问题,进程切换和线程切换有什么区别?

    当然这里的线程指的是同一个进程中的线程。要想正确回答这个问题,需要理解虚拟内存。

    虚拟内存

    虚拟内存是操作系统为每个进程提供的一种抽象,每个进程都有属于自己的、私有的、地址连续的虚拟内存,当然我们知道最终进程的数据及代码必然要放到物理内存上,那么必须有某种机制能记住虚拟地址空间中的某个数据被放到了哪个物理内存地址上,这就是所谓的地址空间映射,那么操作系统是如何记住这种映射关系的呢,答案就是页表。

    每个进程都有自己的虚拟地址空间,进程内的所有线程共享进程的虚拟地址空间

    现在我们就可以来回答这个面试题了。

    进程切换和线程切换的区别

    最主要的一个区别在于进程切换涉及虚拟地址空间的切换而线程不会。因为每个进程都有自己的虚拟地址空间,而线程是共享所在进程的虚拟地址空间的,因此同一个进程中的线程进行线程切换时不涉及虚拟地址空间的转换。

    有的同学可能还是不太明白,为什么虚拟地址空间切换会比较耗时呢?

    现在我们已经知道了进程都有自己的虚拟地址空间,把虚拟地址转换为物理地址需要查找页表,页表查找是一个很慢的过程,因此通常使用Cache来缓存常用的地址映射,这样可以加速页表查找,这个cache就是TLB(translation Lookaside Buffer,我们不需要关心这个名字只需要知道TLB本质上就是一个cache,是用来加速页表查找的)。由于每个进程都有自己的虚拟地址空间,那么显然每个进程都有自己的页表,那么当进程切换后页表也要进行切换,页表切换后TLB就失效了,cache失效导致命中率降低,那么虚拟地址转换为物理地址就会变慢,表现出来的就是程序运行会变慢,而线程切换则不会导致TLB失效,因为线程线程无需切换地址空间,因此我们通常说线程切换要比较进程切换块,原因就在这里。

    参考链接:

    1. https://blog.csdn.net/github_37382319/article/details/97273713

    2. https://blog.csdn.net/xiangwanpeng/article/details/78196539

  • 相关阅读:
    【简单易懂】JPA概念解析:CascadeType(各种级联操作)详解
    [转] @JoinColumn 详解 (javax.persistence.JoinColumn)
    Feign二: @FeignClient 接口调用
    @Basic表示一个简单的属性 懒加载,急加载
    RPC接口测试(一)什么是 RPC 框架
    Mysql中 查询慢的 Sql语句的记录查找
    Mysql 查看连接数,状态 最大并发数
    ntp时间一致对与设备心跳的影响
    jmeter常用四种断言
    jmeter BeanShell断言(四)
  • 原文地址:https://www.cnblogs.com/lfri/p/12597297.html
Copyright © 2011-2022 走看看