Python 升级之路 ( Lv28 ) 并发编程初识

开发
今天我们将学习并发编程涉及的几个概念,包括CPU执行任务的三种方式:串行、并行、并发;程序的三种存在形式:进程、线程、协程以及相关衍生概念;再加上消息通信的两种方式:同步、异步。

今天我们将学习并发编程涉及的几个概念,包括CPU执行任务的三种方式:串行、并行、并发;程序的三种存在形式:进程、线程、协程以及相关衍生概念;再加上消息通信的两种方式: 同步、异步。

今日冒险片段上:

传说暗黑城的尽头每次都会自动改变路径,许多前辈进入这里再也没有出来,暗影迷宫因此得名。了不起从蜘蛛洞穴深入到迷宫后,便发觉这里到处充满了阴森和恐惧。由于长期生活在阴暗潮湿的环境中,精灵们发生了变异,这些类似于人形的上位精灵不但各种属性增强了许多,就连智商也在逐渐与人类接近。  

眼看着就要突破迷宫的出口,三道黑影突然闪现在勇士的面前,嘴里还嘟囔着:“就凭你们也想活着走出这里?先过了我这关再说吧。”说话的这位就是暗影迷宫的领主——影子剑士刹影,边上两位毫无疑问就是这里的将领了。身为阿拉德大陆的冒险家们自然不会因为这句话就胆怯,一场战斗一触即发,俗话说的好“明枪易躲,暗箭难防!”这个强悍的影子剑士居然会鬼剑士的所有技能,什么鬼影步、鬼斩、冰霜萨亚,十分棘手,更可恨是,那两位将领狩魂者和莫比一个不停的在远处释放回旋镖,一个在暗处安放地雷,着实令人头疼。

一、串行 & 并行 & 并发

1. 串行

一句话概: 一个CPU上,按顺序完成多个任务

串行图解:

2. 并发

一句话概括: 一个cpu上, 交替执行多个任务

并发图解:

3. 并行

一句话概括: 多个cpu上, 同时执行多个任务(任务数<=CPU核数)并行必须有多cpu才能实现,否则只能实现并发(伪并行)

并行图解:

串行, 并行, 并发总结如下:

  • 串行:  一个CPU上,按顺序完成多个任务
  • 并行: 多个cpu上, 同时执行多个任务(任务数<=CPU核数)
  • 并发: 一个cpu上, 交替执行多个任务

二、进程 & 线程 & 协程

1. 进程

进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例.程序运行时系统就会创建一个进程,并为它分配资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行.

进程的优点:

  • 可以使用计算机多核,进行任务的并行执行,提高执行效率
  • 运行不受其他进程影响,创建方便
  • 空间独立,数据安全

进程的缺点:

  • 进程的创建和删除消耗的系统资源较多

2. 线程

线程是程序执行时的最小单位,也是CPU调度和分派的基本单位.一个进程可以由很多个线程组成,拥有自己独立的栈和共享的堆,共享堆,不共享栈,标准线程由操作系统调度. 线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行. 同样多线程也可以实现并发操作,每个请求分配一个线程来处理.

多线程多线程可以理解为在同一个程序中能够同时运行多个不同的线程来执行不同的任务,这些线程可以同时利用CPU的多个核心运行. 多线程编程能够最大限度的利用CPU的资源: 如果某些线程不需要占用CPU时间片时, 可以让出当前时间片, 让其他线程获取到CPU资源. 以此来达到最大限度利用CPU资源的目的. 这个过程也被成为上下文切换。

线程生命周期线程主要有“**新建”(NEW)、“就绪”(RUNNABLE)、“运行”(RUNNING)、“阻塞”(BLOCKED)、“死亡”(DEAD)**** 五种状态. 各状态间的转换如下图所示:

注意事项:

  • 在运行过程中,线程由就绪态(RUNNABLE )转为非就绪态(BLOCKED )的过程就是线程上下文切换
  • 线程的状态由运行转为阻塞 ,再由阻塞转为就绪 ,然后再被调度器选中执行,这就是一个上下文切换的过程
  • 当一个线程从运行状态转为阻塞状态时,我们称为一个线程的暂停,线程暂停被切出之后,操作系统会保存相应的上下文,以便这个线程稍后再次进入就绪状态时能够在之前执行进度的基础上继续执行
  • 当一个线程从阻塞状态进入到就绪状态时,我们称为一个线程的唤醒,此时线程将获取上次保存的上下文继续完成执行
  • 频繁的上下文切换会带来系统开销, 因此会导致系统性能下降. 所以我们在使用多线程是应该尽量避免出现上下文切换.

3. 协程

协程也叫作纤程(Fiber),是一种在线程中,比线程更加轻量级的存在,由程序员自己写程序来管理.我们可以将协程理解为运行在线程上的代码块, 协程挂起并不会引起线程阻塞, 他的作用是提高线程的利用率.. 协程之间可以依靠邮箱来进行通信和数据共享, 了避免内存共享数据而带来的线程安全问题. 因为其轻量和高利用率的特点, 即使创建上千个线程也不会对系统造成很大负担, 而线程则恰恰相反. 协程是一种设计思想,不仅仅局限于某一门语言. 在Go, Java, Python 等语言中均有实现。

协程的核心(控制流的让出和恢复):

  • 每个协程有自己的执行栈,可以保存自己的执行现场
  • 可以由用户程序按需创建协程(比如:遇到io操作)
  • 协程“主动让出(yield)”执行权时候,会保存执行现场(保存中断时的寄存器上下文和栈),然后切换到其他协程
  • 协程恢复执行(resume)时,根据之前保存的执行现场恢复到中断前的状态,继续执行,这样就通过协程实现了轻量的由用户态调度的多任务模

进程和线程之间的区别:

  • 每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销.
  • 线程可以看成是轻量级的进程,属于同一进程的线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小.
  • 线程和进程最根本的区别在于:进程是资源分配的单位,线程是调度和执行的单位.
  • 多进程: 在操作系统中能同时运行多个任务(程序).
  • 多线程: 在同一应用程序中有多个顺序流同时执行.
  • 线程是进程的一部分,所以线程有的时候被称为轻量级进程.
  • 一个没有线程的进程是可以被看作单线程的,如果一个进程内拥有多个线程,进程的执行过程不是一条线(线程)的,而是多条线(线程)共同完成的.
  • 系统在运行的时候会为每个进程分配不同的内存区域,但是不会为线程分配内存(线程所使用的资源是它所属的进程的资源),线程组只能共享资源.

线程, 进程, 协程之间区别如图所示:

三、同步 & 异步

同步和异步强调的是消息通信机制。

1. 同步

同步(synchronous):A调用B,等待B返回结果后,A继续执行.在同步的过程中, 存在一个等待的状态. 即: 某个事情执行时需要等待另一个个事情的结果, 才能继续向下执行。

以打电话为例:A向B打电话时, 发出电话邀请, 只有B同意接听之后才会进行通话, 否则会一直处于等待状态(阻塞). 这一过程称为同步。

2. 异步

异步(asynchronous ):A调用B,A继续执行,不等待B返回结果;B有结果了,通知A,A再做处理.

以发短信为例:A在给B发消息, 无需等待B的反馈, 便可以给C发消息. 这一过程成为异步.

今日冒险片段下:

在这千钧一发之际, 了不起突然想到了之前奥菲利亚送的卷轴. 利用这个卷轴可以召唤精灵王伊莎贝拉的虚影, 并存在一段时间. 于是二人便利用精灵王的虚影拖住影子剑士刹影, 先将实力较弱的狩魂者和莫比击败, 然后在三对一的情况下, 花费接近一天的时间, 艰难的将这个剑士击败. 在未来的某一刻, 想到这里, 他们肯定会自豪, 因为他们击败的是一个能自由穿梭时空的职业, 并精通鬼剑士四系职业的第五职业——暗黑武士. 就这样, 击败领主刹影之后, 了不起也顺利的晋升到了lv29.

责任编辑:赵宁宁 来源: Python技术
相关推荐

2024-12-23 16:00:00

GUI编程tkinter

2025-01-20 13:19:02

2025-03-24 10:06:35

2025-02-24 10:17:48

2025-02-18 08:30:00

GUIPythontkinter

2025-03-04 07:40:00

Python模块开发

2025-03-03 10:16:04

2024-12-23 14:54:47

2019-10-24 09:29:13

编程Python程序

2012-03-19 11:41:30

JavaSocket

2021-12-12 18:15:06

Python并发编程

2023-10-18 15:19:56

2015-07-28 17:11:00

编程技术提升

2012-12-28 13:35:37

网络无线网络

2023-07-03 09:59:00

并发编程并发容器

2019-03-06 16:00:14

服务器架构系统

2018-03-21 21:31:28

Java9编程Java

2017-01-10 13:39:57

Python线程池进程池

2017-09-19 14:53:37

Java并发编程并发代码设计

2009-09-08 14:30:57

CCNA认证考试
点赞
收藏

51CTO技术栈公众号