【2020Python修炼记】python并发编程(二)多进程-理论部分
【目录】
一、什么是进程
二、进程与程序的区别
三、进程的并行与并发
四、多道技术
五、同步 、异步 / 阻塞、非阻塞的概念
一、什么是进程(Process)
# 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。
简单地说,进程 就是 正在进行的一个过程或者说一个任务。而负责执行任务则是cpu。
在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;
在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。
# 狭义定义:进程是正在运行的程序的实例(an instance of a computer program that is being executed)。
# 广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。
# 操作系统引进进程概念的原因:
从理论角度看,是对正在运行的程序过程的抽象;
从实现角度看,是一种数据结构,目的在于清晰地刻画动态系统的内在规律,有效管理和调度进入计算机系统主存储器运行的程序。
二、进程与程序的区别
程序仅仅只是一堆代码而已,而进程指的是程序的运行过程。
需要强调的是:同一个程序执行两次,那也是两个进程,比如打开暴风影音,虽然都是同一个软件,但是一个可以播放李健,一个可以播放周杰伦。
三、进程的并行与并发
(1)并行 : 并行是指两者同时执行。
只有具备多个cpu才能实现并行;资源够用,比如三个线程,四核的CPU )
比如赛跑,两个人都在不停的往前跑。
(2)并发 : 并发是指资源有限的情况下,两者交替轮流使用资源。
并发是伪并行,即看起来是同时运行。单个cpu+多道技术就可以实现并发,(并行也属于并发)
比如一段路(单核CPU资源)同时只能过一个人,A走一段后,让给B,B用完继续给A ,交替使用,目的是提高效率。
(3)区别:
并行是从微观上,也就是在一个精确的时间片刻,有不同的程序在执行,这就要求必须有多个处理器。
并发是从宏观上,在一个时间段上可以看出是同时执行的,比如一个服务器同时处理多个session。
四、多道技术——空间上的复用+时间上的复用
1.产生背景:针对单核,实现并发
ps: 现在的主机一般是多核,那么每个核都会利用多道技术 有4个cpu,运行于cpu1的某个程序遇到io阻塞,
会等到io结束再重新调度,会被调度到4个 cpu中的任意一个,具体由操作系统调度算法决定。
2.空间上的复用:如内存中同时有多道程序
3.时间上的复用:复用一个cpu的时间片
强调:遇到io切,占用cpu时间过长也切,核心在于切之前将进程的状态保存下来,
这样 才能保证下次切换回来时,能基于上次切走的位置继续运行
五、同步 、异步 / 阻塞、非阻塞的概念
1、进程三态——就绪态,运行态,阻塞态
在程序运行的过程中,由于被操作系统的调度算法控制,程序会进入几个状态:就绪,运行和阻塞。
(1)就绪(Ready)状态
当进程已分配到除CPU以外的所有必要的资源,只要获得处理机便可立即执行,这时的进程状态称为就绪状态。
(2)执行/运行(Running)状态
当进程已获得处理机,其程序正在处理机上执行,此时的进程状态称为执行状态。
(3)阻塞(Blocked)状态
正在执行的进程,由于等待某个事件发生而无法执行时,便放弃处理机而处于阻塞状态。引起进程阻塞的事件可有多种,
例如,等待I/O完成、申请缓冲区不能满足、等待信件(信号)等。
2、同步/异步——描述的是任务的提交方式,即 针对的是函数/任务的调用方式
(1)所谓同步,就是一个任务A 的完成需要依赖另外一个任务B 时,只有等待被依赖的任务B 完成后,依赖的任务A 才能算完成,这是一种可靠的任务序列
。要么成功都成功,失败都失败,两个任务的状态可以保持一致。即 在发出一个功能调用时,在没有得到结果之前,该调用就不会返回。
——例如:啥也不干,干等着你,等你决定好了 再一起吃饭
(2)所谓异步,是不需要等待被依赖的任务B 完成,只是通知被依赖的任务B 要完成什么工作,依赖的任务A 也立即执行,只要自己完成了,整个任务就算完成了
。至于被依赖的任务B 最终是否真正完成,依赖它的任务A 无法确定,所以它是不可靠的任务序列
。即 异步的概念和同步相对。当一个异步功能调用发出后,调用者不能立刻得到结果。当该异步功能完成后,通过状态、通知或回调来通知调用者。
——例如:通知你去吃饭,然后自己先忙别的,等忙完了,再决定是否一起吃饭,可能自己到后面先去吃饭
3、阻塞/非阻塞——描述的程序的运行状态,即 针对的是进程或线程
阻塞和非阻塞,这两个概念与程序(线程)等待消息通知(无所谓同步或者异步)时的状态有关。
也就是说阻塞与非阻塞主要是程序(线程)等待消息通知时的状态角度来说的
(1)阻塞
# 阻塞调用是指调用结果返回之前,当前线程会被挂起(如遇到io操作)。函数只有在得到结果之后才会将阻塞的线程激活。
有人也许会把阻塞调用和同步调用等同起来,实际上他是不同的。对于同步调用来说,很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回而已。
#举例:
#1. 同步调用:apply一个累计1亿次的任务,该调用会一直等待,直到任务返回结果为止,但并未阻塞住(即便是被抢走cpu的执行权限,那也是处于就绪态);
#2. 阻塞调用:当socket工作在阻塞模式的时候,如果没有数据的情况下调用recv函数,则当前线程就会被挂起,直到有数据为止。
(2)非阻塞
# 非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前也会立刻返回,同时该函数不会阻塞当前线程。
参考资料:
https://www.cnblogs.com/Dominic-Ji/articles/10929384.html
https://zhuanlan.zhihu.com/p/111136095
🐱不负韶华,只争朝夕🍚