当前位置:   article > 正文

【计算机基础】多进程,多线程,多协程介绍

多协程

基础概念

PC一次可以开启多个进程处理多个任务:多进程
一个进程中可以启动N个线程:多线程;
一个线程中可以启动N个协程:多协程。

一、多进程

进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。

在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体

可以简单地理解为操作系统中正在执行的程序。也就说,每个应用程序都有一个自己的进程。

每一个进程启动时都会最先产生一个线程,即主线程。然后主线程会再创建其他的子线程。

  • 优点: 可以利用多核CPU并行运算
  • 缺点: 占用资源多、可启动数目比线程少
  • 适用于: CPU密集型计算

1. 同步/异步

所谓同步就是一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成,这是一种可靠的任务序列。要么成功都成功,失败都失败,两个任务的状态可以保持一致。

所谓异步不需要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工作,依赖的任务也立即执行,只要自己完成了整个任务就算完成了。至于被依赖的任务最终是否真正完成,依赖它的任务无法确定,所以它是不可靠的任务序列

2. 阻塞/非阻塞

阻塞和非阻塞这两个概念与程序等待消息通知(无所谓同步或者异步)时的状态有关。也就是说阻塞与非阻塞主要是程序(线程)等待消息通知时的状态角度来说的

3. 并发/并行

  • 并行 : 并行是指多个任务同时执行,比如两个男人同时在给自己女朋友发微信。

  • 并发 : 并发是多个任务交替轮流使用资源,比如一个男人在给他7个女朋友发微信,只要他发的够快,宏观上来说他在同时聊7个人。

4. 进程状态与调度

在这里插入图片描述
在了解其他概念之前,我们首先要了解进程的几个状态。在程序运行的过程中,由于被操作系统的调度算法控制,程序会进入几个状态:就绪运行阻塞

(1)就绪(Ready)状态

当进程已分配到除CPU以外的所有必要的资源,只要获得处理机便可立即执行,这时的进程状态称为就绪状态。

(2)执行/运行(Running)状态当进程已获得处理机,其程序正在处理机上执行,此时的进程状态称为执行状态。

(3)阻塞(Blocked)状态正在执行的进程,由于等待某个事件发生而无法执行时,便放弃处理机而处于阻塞状态。引起进程阻塞的事件可有多种,例如,等待I/O完成、申请缓冲区不能满足、等待信件(信号)等。
在这里插入图片描述

二、多线程

现在的CPU都是多核的,使用多线程能充分利用CPU来提供程序的执行效率。(python例外)

线程是一个基本的CPU执行单元。它必须依托于进程存活。一个线程是一个execution context(执行上下文),即一个CPU执行时所需要的一串指令

  • 优点: 相比进程,更轻量级、占用资源少
  • 缺点:
    • 相比进程,python多线程不能并发执行,不能利用多CPU(GIL);(只能使用一个CPU)
    • 相比协程,启动数目有限制,占用内存资源,有线程切换开销
  • 适用于: I/O密集型计算、同时运行的任务数目要求不多

既然进程这么优秀,为什么还要线程呢?其实,仔细观察就会发现进程还是有很多缺陷的,主要体现在两点上:

  • 进程只能在一个时间干一件事,如果想同时干两件事或多件事,进程就无能为力了。
  • 进程在执行的过程中如果阻塞,例如等待输入,整个进程就会挂起,即使进程中有些工作不依赖于输入的数据,也将无法执行。

进程是资源分配的最小单位, 线程是CPU调度的最小单位.
每一个进程中至少有一个线程。

1. 线程的类型

线程的因作用可以划分为不同的类型。大致可分为:

  • 主线程
  • 子线程
  • 守护线程(后台线程)
  • 前台线程

2. 线程的特点

在多线程的操作系统中,通常是在一个进程中包括多个线程,每个线程都是作为利用CPU的基本单位,是花费最小开销的实体。线程具有以下属性。

1)轻型实体
线程中的实体基本上不拥有系统资源,只是有一点必不可少的、能保证独立运行的资源。
线程的实体包括程序、数据和TCB。线程是动态概念,它的动态特性由线程控制块TCB(Thread Control Block)描述。

TCB包括以下信息:
(1)线程状态。
(2)当线程不运行时,被保存的现场资源。
(3)一组执行堆栈。
(4)存放每个线程的局部变量主存区。
(5)访问同一个进程中的主存和其它资源。
用于指示被执行指令序列的程序计数器、保留局部变量、少数状态参数和返回地址等的一组寄存器和堆栈。

2)独立调度和分派的基本单位。
在多线程OS中,线程是能独立运行的基本单位,因而也是独立调度和分派的基本单位。由于线程很“轻”,故线程的切换非常迅速且开销小(在同一进程中的)

3)共享进程资源。
线程在同一进程中的各个线程,都可以共享该进程所拥有的资源,这首先表现在:所有线程都具有相同的进程id,这意味着,线程可以访问该进程的每一个内存资源;此外,还可以访问进程所拥有的已打开文件、定时器、信号量机构等。由于同一个进程内的线程共享内存和文件,所以线程之间互相通信不必调用内核

4 )可并发执行。
在一个进程中的多个线程之间,可以并发执行,甚至允许在一个进程中所有线程都能并发执行;同样,不同进程中的线程也能并发执行,充分利用和发挥了处理机与外围设备并行工作的能力。

在这里插入图片描述
不同的进程之间是充满敌意的,彼此是抢占、竞争cpu的关系,如果迅雷会和QQ抢资源。

而同一个进程是由一个程序员的程序创建,所以同一进程内的线程是合作关系,一个线程可以访问另外一个线程的内存地址,大家都是共享的,一个线程干死了另外一个线程的内存,那纯属程序员脑子有问题。

类似于进程,每个线程也有自己的堆栈,不同于进程,线程库无法利用时钟中断强制线程让出CPU,可以调用thread_yield运行线程自动放弃cpu,让另外一个线程运行。

线程通常是有益的,但是带来了不小程序设计难度,线程的问题是:

  1. 父进程有多个线程,那么开启的子线程是否需要同样多的线程

  2. 在同一个进程中,如果一个线程关闭了文件,而另外一个线程正准备往该文件内写内容呢?加锁来防止数据竞争(data race)

三、多协程

  • 优点: 内存开销最少、启动协程数量最多
  • 缺点: 支持的库有限制(aiohttp可以用,requests不能用)、代码实现复杂
  • 适用于: IO密集型计算、需超多任务运行、但有现成库支持的场景

补充说明

一、CPU密集型计算和IO密集型计算

CPU密集型
即计算密集型,I/O在很短的时间就可以完成,但CPU需要大量的计算和处理,特点是CPU占用率很高
例如:压缩和解压缩、加密和解密、正则表达式搜索

IO密集型
指系统运作大部分的状况是CPU在等I/O(硬盘/内存)的读/写操作,CPU占用率较低。
例如:文件处理程序、网络爬虫程序、读写数据库

二、多进程与多线程的区别与联系

区别:

  • 线程必须在某个进程中执行。
  • 一个进程可包含多个线程,其中有且只有一个主线程。
  • 地址空间和其它资源(如打开文件):进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。
    • 多线程共享同个地址空间、打开的文件以及其他资源。
    • 多进程共享物理内存、磁盘、打印机等物理资源。
  • 通信: 进程间通信 IPC ,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要 进程同步 和互斥手段的辅助,以保证数据的一致性。
  • 调度和切换:线程上下文切换比进程上下文切换要快得多。
  • 在多线程操作系统中,进程不是一个可执行的实体。

关系:
在这里插入图片描述

三、如何选择

在这里插入图片描述
下面列出的为python对应的第三方库:

  1. 如果是CPU密集型,首选多进程multiprocessing
  2. 如果需要超多任务量,倾向于多协程;
  3. 如果没有有现成协程库支持,无法选择多协程asynico,只能选择多线程threading;
  4. 如果协程的程序复杂度过高,那就选择多线程threading。

参考链接:
https://www.bilibili.com/video/BV1bK411A7tV?p=2&spm_id_from=pageDriver
https://www.cnblogs.com/haitaoli/articles/10302508.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/151404?site
推荐阅读
相关标签
  

闽ICP备14008679号