zoukankan      html  css  js  c++  java
  • 进程、线程、协程(转)

    进程是执行着的应用程序,而线程是进程内部的一个执行序列。一个进程可以有多个线程。线程又叫做轻量级进程。

    进程是让操作系统的伪并发性成为可能

    线程是让进程里面内部子任务的并发成为可能

    最终目标是提高cpu的利用率

    进程是系统分配的最小单元,线程是cpu调度的最小单元

    进程是具有一定功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源调度和分配的一个独立单位。

    线程是进程的实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。

    一个进程可以有多个线程,多个线程也可以并发执行

    进程的生命周期:创建-就绪-运行-等待-死亡

    线程的生命周期:新建-就绪-运行-阻塞-等待-锁池-死亡

    两者的对比:

    1、调度方面:在引入线程的OS中,线程是独立的调度和分派单位,而进程作为资源的拥有单位(相当于把未引入线程的传统OS中的进程的两个属性分开了)。由于线程不拥有资源,因此可以显著的提高并发度以及减少切换开销。

    2、并发性:引入了线程的OS中,进程间可以并发,而且一个进程内部的多个线程之间也是可以并发的,这就使OS具有更好的并发性,有效的提高了系统资源利用率和吞吐量。

    3、拥有资源:无论OS是否支持线程,进程都是基本的资源拥有单位,线程只拥有很少的基本的资源,但是线程可以访问所隶属的进程的资源(进程的代码段,数据段和所拥有的系统资源如fd)

    4、系统开销:创建或者撤销进程的时候,系统要为之创建或回收PCB,系统资源等,切换时也需要保存和恢复CPU环境。而线程的切换只需要保存和恢复少量的寄存器,不涉及存储器管理方面的工作,所以开销较小。此外,统一进程中的多个线程由于共享地址空间,所以通信同步等都比较方便。

    如何理解一个程序可以对应多个进程,一个进程也可以对应多个程序?

            一个程序可以重复运行,开几个窗口,比如网游的“双开”,一个进程可以对应多个程序就是一个DLL文件可以被多个程序运用,比如DirectX9的动态链接库,就是,许多游戏都要有它才能运行。这就如同的车和路的关系,要去一个地方,可以有多条路,而一条路也可到达多个地方。

    从其他方面诠释:

            一开始大家想要同一时间执行那么三五个程序,大家能一块跑一跑。特别是UI什么的,别一上计算量比较大的玩意就跟死机一样。于是就有了并发,从程序员的角度可以看成是多个独立的逻辑流。内部可以是多cpu并行,也可以是单cpu时间分片,能快速的切换逻辑流,看起来像是大家一块跑的就行。

            但是一块跑就有问题了。我计算到一半,刚把多次方程解到最后一步,你突然插进来,我的中间状态咋办,我用来储存的内存被你覆盖了咋办?所以跑在一个cpu里面的并发都需要处理上下文切换的问题。进程就是这样抽象出来的一个概念,搭配虚拟内存、进程表之类的东西,用来管理独立的程序运行、切换。

            后来一个电脑上有了好几个cpu,好咧,大家都别闲着,一人跑一个进程。就是所谓的并行。

            因为程序的使用涉及大量的计算机资源配置,把这活随意的交给用户程序,非常容易让整个系统分分钟被搞跪,资源分配也很难做到相对的公平。所以核心的操作需要陷入内核(kernel),切换到操作系统,让老大帮你来做。

            有的时候碰着I/O访问,阻塞了后面所有的计算。空着也是空着,老大就直接把CPU切换到其他进程,让人家先用着。当然除了IO阻塞,还有时钟阻塞等。一开始大家都这样弄,后来发现不成,太慢了。为啥呀,一切换进程得反复进入内核,置换掉一大堆状态。进程数一高,大部分系统资源就被进程切换给吃掉了。后来搞出线程的概念,大致意思就是,这个地方阻塞了,但我还有其他地方的逻辑流可以计算,这些逻辑流是共享一个地址空间的,不用特别麻烦的切换页表、刷新TLB,只要把寄存器刷新一遍就行,能比切换进程开销少点。

            如果连时钟阻塞、 线程切换这些功能我们都不需要了,自己在进程里面写一个逻辑流调度的东西。那么我们即可以利用到并发优势,又可以避免反复系统调用,还有进程切换造成的开销,分分钟给你上几千个逻辑流不费力。这就是用户态线程。

            从上面可以看到,实现一个用户态线程有两个必须要处理的问题:一是碰着阻塞式IO会导致整个进程被挂起;二是由于缺乏时钟阻塞,进程需要自己拥有调度线程的能力。如果一种实现使得每个线程需要自己通过调用某个方法,主动交出控制权。那么我们就称这种用户态线程是协作式的,即是协程。

            本质上协程就是用户空间下的线程。

    用户线程与内核线程

           根据操作系统内核是否对线程可感知,可以把线程分为内核线程和用户线程。

    引入用户线程,具体而言,有以下四个方面的优势:

        (1)可以在不支持线程的操作系统中实现。
        (2)创建和销毁线程、线程切换代价和线程管理的代价比内核线程少得多。
        (3)允许每个进程定制自己的调度算法,线程管理比较灵活。
        (4)用户线程能够利用的表空间和堆栈空间比内核级线程多。

    用户线程的缺点主要有以下两点:
        (1)同一进程中只能同时有一个线程在运行,如果有一个线程使用了系统调用而阻塞,那么整个进程都会被挂起。
        (2)页面失效也会产生类似的问题。

    参考链接:

    https://mp.weixin.qq.com/s/zuWRx1FGuBC-_HwuA7jK3w

    原文:https://blog.csdn.net/qq_35642036/article/details/82798749 

  • 相关阅读:
    js 操作文件
    Thymeleaf在js中使用表达式
    JUnit5常用注解
    .Net开发步骤
    springboot自定义 HandlerMapping
    期末加分+总结
    SAP ABAP 性能优化技巧 – 修改一组纪录
    SAP ABAP 性能优化技巧 – 视图取代基本表
    Sql Server 日期格式化函数 (转)
    SAP ABAP 性能优化技巧 — 使用二分查找(Binary Search)选项
  • 原文地址:https://www.cnblogs.com/NetPig/p/10917362.html
Copyright © 2011-2022 走看看