今天和boss闲聊,提到了进程和线程,boss问我进程和线程什么关系,我心想这不so easy,一个程序就相当于一个进程,进程可以有很多线程,巴拉巴拉。。。boss又问道,“那协程呢?”。我:“携程?”,boss于是从头至尾跟我讲了一遍这三者的关系,这篇博客就来整理总结一下。

1 进程

进程就是一个在内存中运行的应用程序,进程是操作系统进行资源分配和调度的基本单位。每个进程都有自己独立的一块内存空间用来拥有代码、打开的文件资源、数据资源,比如在Windows系统中,一个运行的xx.exe就是一个进程。下面是最熟悉不过的任务管理器:

图中的每一个应用,每一个后台进程,都是一个进程。

进程有五种状态:创建、就绪、阻塞、运行、关闭,转换关系如下:

2 线程

线程是进程中的一个最小的执行任务(执行单元或控制单元)负责当前进程中程序的执行。一个进程至少有一个线程,一个进程可以运行多个线程,多个线程可共享数据。与进程不同的是同类的多个线程共享进程(所拥有的全部资源)的堆和方法区资源,但每个线程有自己的程序计数器、虚拟机栈和本地方法栈,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。

进程 线程
根本区别 操作系统资源分配的基本单位 处理器任务调度和执行的基本单位
资源开销 每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销; 线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。
包含关系 如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的 线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。
内存分配 同一进程的线程共享本进程的地址空间和资源, 进程之间的地址空间和资源是相互独立的
影响关系 一个进程崩溃后,在保护模式下不会对其他进程产生影响 一个线程崩溃则所在进程终止,所以多进程要比多线程健壮
执行过程 每个独立的进程有程序运行的入口、顺序执行序列和程序出口。 线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制,两者均可并发执行

线程具有许多传统进程所具有的特征,故又称为轻型进程(Light—Weight Process)或进程元;而把传统的进程称为重型进程(Heavy—Weight Process),它相当于只有一个线程的任务。在引入了线程的操作系统中,通常一个进程都有若干个线程,至少包含一个线程。


从 JVM 角度说进程和线程之间的关系(重要)

Java 内存区域:

从上图可以看出:一个进程中可以有多个线程,多个线程共享进程的堆和方法区 (JDK1.8 之后的元空间)资源,但是每个线程有自己的程序计数器、虚拟机栈 和 本地方法栈,也就是说程序计数器、虚拟机栈、本地方法栈都是线程私有的:

作用 线程私有/共享
程序计数器 1.字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理。2.在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到的位置。需要注意的是,如果执行的是 native 方法,那么程序计数器记录的是 undefined 地址,只有执行的是 Java 代码时程序计数器记录的才是下一条指令的地址。程序计数器私有主要是为了线程切换后能恢复到正确的执行位置。 私有
虚拟机栈 每个 Java 方法在执行的同时会创建一个栈帧用于存储局部变量表、操作数栈、常量池引用等信息。从方法调用直至执行完成的过程,就对应着一个栈帧在 Java 虚拟机栈中入栈和出栈的过程。 为了保证线程中的局部变量不被别的线程访问到
本地方法栈 和虚拟机栈所发挥的作用非常相似,区别是: 虚拟机栈为虚拟机执行 Java 方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。 在 HotSpot 虚拟机中和 Java 虚拟机栈合二为一。
进程中最大的一块内存,主要用于存放新创建的对象 (所有对象都在这里分配内存) 共享
方法区 主要用于存放已被加载的类信息、常量、静态变量、即时编译器编译后的代码等数据

3 协程

        协程(Coroutines)是一种比线程更加轻量级的存在。正如一个进程可以拥有多个线程一样,一个线程也可以拥有多个协程。它就是一个函数,一个特殊的函数——可以在某个地方挂起,并且可以重新在挂起处继续运行。所以说,协程与进程、线程相比,不是一个维度的概念。
一个进程可以包含多个线程,一个线程也可以包含多个协程,也就是说,一个线程内可以有多个那样的特殊函数在运行。

一个线程内的多个协程的运行一定是串行的。如果有多核CPU的话,多个进程或一个进程内的多个线程是可以并行运行的,但是一个线程内的多个协程却绝对串行的,无论有多少个CPU(核)。协程本质就是一个函数。一个线程内可以运行多个函数,但是这些函数都是串行运行的。当一个协程运行时,其他协程必须挂起。协程不是被操作系统内核所管理的,而是完全由程序所控制,也就是在用户态执行。这样带来的好处是性能大幅度的提升,因为不会像线程切换那样消耗资源。协程与进程、线程相比不是一个维度的概念
4 协程与进程一样,它们的切换都存在上下文切换问题。
进程、线程、协程上下文切换的比较:

进程 线程 协程
切换者(管理者) 操作系统 操作系统 用户(编程者/应用程序)
切换时机 根据操作系统自己的切换策略,用户不感知 根据操作系统自己的切换策略,用户不感知 用户自己(程序)决定
切换内容

页全局目录

内核栈

硬件上下文

内核栈

硬件上下文

硬件上下文

切换内容的保存 保存于内核栈中 保存于内核栈中 保存于用户自己的变量(用户栈或者堆)
切换过程 用户态-内核态-用户态 用户态-内核态-用户态 用户态(没有陷入内核态)
切换效率

协程的使用场景
        一个线程内的多个协程是串行执行的,不能利用多核,所以,显然,协程不适合计算密集型的场景。协程适合I/O 阻塞型。I/O本身就是阻塞型的(相较于CPU的时间世界而言)。就目前而言,无论I/O的速度多快,也比不上CPU的速度,所以一个I/O相关的程序,当其在进行I/O操作时候CPU实际上是空闲的。
        假设1个线程有5个I/O子程序要处理。如果绝对串行化,当其中一个I/O阻塞时,其他4个I/O并不能得到执行,5个I/O必须排队等待,依次处理,当前面一个I/O阻塞时,后面4个始终处于等待状态:

而协程能比较好地处理这个问题,当一个协程(特殊子进程)阻塞时,它可以切换到其他没有阻塞的协程上去继续执行,这样就能得到比较高的效率:

上面举的例子是5个I/O处理,可见I/O阻塞时,利用协程来处理,切换效率比较高。但假设每秒500、50000、5000000个I/O呢?已经达到了“I/O密集型”的程度,因为协程没有利用多核的能力,这种情况协程将无能为力,需要使用“多进程+协程”。

Neutorn可以归类为I/O阻塞型,所以在Neutorn的代码中处处可见协程的相关代码。

简述进程、线程、协程相关推荐

  1. linux的进程/线程/协程系列5:协程的发展复兴与实现现状

    协程的发展复兴与实现现状 前言 本篇摘要: 1. 协同制的发展史 1.1 协同工作制的提出 1.2 自顶向下,无需协同 1.3 协同式思想的应用 2. 协程的复兴 2.1 高并发带来的问题 2.2 制 ...

  2. linux的进程/线程/协程系列1:进程到协程的演化

    linux的进程/线程/协程系列1:进程到协程的演化 前言 摘要: 1. 一些历史:批处理时代 2. 现代操作系统启动过程 3. 进程(process)的出现 4. 线程(thread)与线程池 5. ...

  3. 简要说明__python3中的进程/线程/协程

    多任务可以充分利用系统资源,极大提升程序运行效率,多任务的实现往往与 多线程,多进程,多协程有关 稳定性: 进程 > 线程 > 协程 系统资源占用量:进程 > 线程 > 协程 ...

  4. Linux的进程/线程/协程系列4:进程知识深入总结:上篇

    Linux的进程/线程/协程系列4:进程/线程相关知识总结 前言 本篇摘要: 1. 进程基础知识 1.1 串行/并行与并发 1.2 临界资源与共享资源 1.3 同步/异步与互斥 1.4 进程控制原语 ...

  5. linux的进程/线程/协程系列3:查看linux内核源码——vim+ctags/find+grep

    linux的进程/线程/协程系列3:查看linux内核源码--vim+ctags/find+grep 前言 摘要: 1. 下载linux内核源码 2. 打标签方法:vim+ctags 2.1 安装vi ...

  6. Python之进程+线程+协程(异步、selectors模块、阻塞、非阻塞IO)

    文章目录 一.IO多路复用 二.selectors模块 本篇文字是关于IO多路复用的更深入一步的总结,上一篇 Python之进程+线程+协程(事件驱动模型.IO多路复用.select与epoll)对I ...

  7. 进程 线程 协程 各自的概念以及三者的对比分析

    文章目录 1 进程 2 线程 3 进程和线程的区别和联系 3.1 区别 3.2 联系 4 举例说明进程和线程的区别 5 进程/线程之间的亲缘性 6 协程 线程(执行一个函数)和协程的区别和联系 协程和 ...

  8. 进程 线程 协程_进程,线程,协程那些事

    无论我们写出怎样的程序,最后都是由操作系统来运行我们的程序,而操作系统如何管理我们的程序,我们程序的数据如何保存和计算,这些都是操作系统需要处理的事情,我们只要将写好的程序交给操作系统就好. 虽然操作 ...

  9. python进程线程协程区别_Python3多线程与协程

    python中的多线程非常的常用,之前一直糊里糊涂地使用,没有一些系统性的概念,记录一下~ 0x001 多线程的优势:可将长时间占用的程序放到后台 可能会加速程序执行速度 能够实现一些类似同步执行的效 ...

  10. Go进程/线程/协程:单元 空间资源 切换 共享

    https://www.imooc.com/article/31751 进程process 线程 thread   协程goroutine 操作系统分为操作与资源两部分,操作就是方法,资源就是硬盘资源 ...

最新文章

  1. 软件测试真实项目_企业中软件测试的项目流程
  2. vue+axios天气查询——天知道效果展示及源码分析
  3. java搜索文件_Java如何在目录中搜索文件?
  4. mysql子分区多少层_MySQL 子分区-阿里云开发者社区
  5. 清空输入缓冲区fflush()
  6. mysql查看innodb版本_mysql中查看innodb版本的方法
  7. 那年学过的Java笔记二SE面向对象
  8. 光子能变成正负电子,能不能变成其他正反物质?
  9. win和linux生成的密文不一样,AES加密解密Windows下跟linux下结果不同的解决方案
  10. vba html 教程 pdf,Word VBA教程:CanvasShapes集合
  11. GJB289A总线测试工装研究
  12. c语言免杀程序源码,[原创]Window下基于C/C++源码免杀理论及思路(新手篇)
  13. java adminlte 使用_AdminLTE框架基础布局使用
  14. Scrapy豆瓣电影top250(excel保存和图片下载)
  15. 014基于SSH航空订票系统air
  16. easyUI datagrid 遍历集合
  17. 剑灵狂欢区服务器位置,9377剑灵洪门崛起6月25日部分区合服公告
  18. 夏普给鸿海带来哪些改变?
  19. 运用HTML+CSS做CSDN博客首页
  20. 魔改Win11 系统焕然一新,颜值和性能飙升

热门文章

  1. SQL Server: 数据库模式SCHEMA
  2. 抽奖随机滚动_手把手教你制作EXCEL抽奖器,只需两步轻松搞定
  3. org.apache.rocketmq.remoting.exception.RemotingConnectException: connect to localhost:9876 failed
  4. LargestNumber
  5. 饥饿背后:小米供应链的秘密
  6. 启动WPS for Linux后,出现提示系统缺失字体解决办法
  7. 海洋主题绘画_海底世界主题绘画教案
  8. 如何去除视频上的水印?
  9. 出现这十种症状,说明你不适合干程序员这个行当
  10. 苹果生产日期对照表2020_【穿戴】AirPodsPro出现声音问题 你中招了么?苹果:免费更换|airpods|pixel|无线耳机|谷歌...