进程,线程,协程,同步,并发,异步

进程,线程,协程,同步,并发,异步,第1张

1,我们公司一开始带饭的人不是很多,公司只有一个茶水间,于是行政的小姐姐很体贴的买了一个微波炉放到茶水间,然后大家中午可以在茶水间排队去热饭。很开心。

2,后来公司发展越来越好,不断有新鲜的血液注入到公司,充满了活力,带饭的人越来越多,行政小姐姐发现一个微波炉根本不够用,于是又卖了两个,大家中午继续去茶水间排队去热饭,速度比以前快了许多,大大缓解了排队过长的压力。

3,某一天公司上市了,发展一片大好,人员也越来越多,于是公司换了新的办公地点,将原来的一个茶水间扩充到了3个,微波炉每个茶水间放5个,同时雇了一个阿姨,专门辅助员工的一些生活方面的事,让员工可以安安心心工作,于是变成了这样,到中午的时候,员工选择3个茶水间一个,将饭盒放在茶水间里,阿姨负责将饭热好放到指定位置,一个阿姨就可以同时 *** 作多个微波炉,一个热好后取出放入下一个,大大提高了热饭效率,热好的饭可以放到指定位置一会自己来取即可,也可以送到员工的位置,大家中午再也不用排队热饭了,

多个茶水间相当于多进程(放在python也可以理解为多核),大大提高了效率,但同时开销也很多,增加一个茶水间的代价远大于增加一个微波炉。

进程,直观点说,保存在硬盘上的程序运行以后,会在内存空间里形成一个独立的内存体,这个内存体 有自己独立的地址空间,有自己的堆 ,上级挂靠单位是 *** 作系统。 *** 作系统会以进程为单位,分配系统资源(CPU时间片、内存等资源),进程是资源分配的最小单位 。

大家排队去茶水间热饭,先到的先热,同一茶水间同时只有一个人在热饭。即使有多个微波炉也是顺序的开始工作,三个微波炉相当于三个线程,同时可以热三份饭,但热饭的人是顺序进入茶水间的。

线程,有时被称为轻量级进程(Lightweight Process,LWP),是 *** 作系统调度(CPU调度)执行的最小单位 。

阿姨可以同时 *** 作多个微波炉,一誉手态个热好后取出放入下一个,大大提高了热饭效率,哪个微波炉热好就先用哪个,所以协程是无序的,大大提高了工作效率。

一个阿姨在多个茶水间和微波炉工作 充分利用多核

协程,是一种比线程更加轻量级的存在,协程不是被 *** 作系统内核所管理,而完全是由程序所控制(也就是在用户态执行)。这样带来的好处就是性能得到了很大的提升,不会像线程切换那样消耗资源。

协程在子程序内部是可中断的,然后转而执行别的子程序,在适当的时候再返回来接着执行 。

阿姨热好饭之后放到指定位置,每个人可以根据自己的时间过来取,如果阿姨空闲了也可以送到员工工位。

公司初期人员较少,所有员工在唯一的一个茶水间排队使用同一个微波炉,顺序使用微波炉。

公司中期增加了微波炉的数量,所有员工在茶水间排队使用多个微波炉,多个微波炉同时工作。

公司发展后期增加了茶水间和微波炉的数量,只有一个阿姨使用多个茶水间的微波炉,只有在微波炉可以使用的条件下才去使用,其他时间可以干其他事情。

【区别】:

调度 : 线程作为调度和分配的基本单位,进程作为拥有资源的基本单位 ;

并发性 : 不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行 ;

拥有资源 : 进程是拥有资源的一个独立单位,线程不拥有系统资源 ,但可以访问隶属于进程的资源。进程所维护的是程序所包含的资庆源源(静态资源), 如: 地址空间,打开的文件句柄集,文件系统状态,信号处理handler等 ;线程所维护的运行相关的资源(动态资源),如: 运行栈,调度相关的控制信息,待处理的信号集等 ;

系统开销 :在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。但是进程有独立的地址空间,一个进程崩溃后薯余,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个进程死掉就等于所有的线程死掉,所以 多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些 。

【联系】:

一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程 ;

资源分配给进程,同一进程的所有线程共享该进程的所有资源;

处理机分给线程,即 真正在处理机上运行的是线程 ;

线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。

协程的特点在于是一个线程执行,那和多线程比,协程有何 优势 ?

极高的执行效率 :因为 子程序切换不是线程切换,而是由程序自身控制 ,因此, 没有线程切换的开销 ,和多线程比,线程数量越多,协程的性能优势就越明显;

不需要多线程的锁机制 :因为只有一个线程,也不存在同时写变量冲突, 在协程中控制共享资源不加锁 ,只需要判断状态就好了,所以执行效率比多线程高很多。

(1)进程可使用multiprocessing包实现

与threading.Thread类似,它可以利用multiprocessing.Process对象来创建一个进程。

该进程可以运行在Python程序内部编写的函数。

该Process对象与Thread对象的用法相同,也有start(), run(), join()的方法。

(2)线程可使用threading包或thread包

(3)协程通过async await 实现,async声明一个函数为异步函数,await可将程序挂起,去执行其他的异步程序。协程 有两种,一种 无栈协程,python 中 以 asyncio 为代表, 一种有栈协程,python 中 以 gevent 为代表。

(1)以多进程形式,允许多个任务同时运行;

(2)以多线程形式,允许单个任务分成不同的部分运行;

(3)提供协调机制,一方面防止进程之间和线程之间产生冲突,另一方面允许进程之间和线程之间共享资源。

asyncio 是 Python 中的异步IO库,用来编写并发协程,适用于IO阻塞且需要大量并发的场景,例如爬虫、文件读写。

asyncio 在 Python3.4 被引入,经过几个版本的迭代,特性、语法糖均有了不同程度的改进,这也使得不同版本的 Python 在 asyncio 的用法上各不相同,显得有些杂乱,以前使用的时候也是本着能用就行的原则,在写法上走了一些弯路,现在对 Python3.7+ 和 Python3.6 中 asyncio 的用法做一个梳理,以便以后能更好的使用。

协程,又称微线程,它不被 *** 作系统内核所管理,而完全是由程序控制,协程切换花销小,因而有更高的性能。

协程可以比作子程序,不同的是,执行过程中协程可以挂起当前状态,转而执行其他协程,在适当的时候返回来接着执行,协程间的切换不需要涉及任何系统调用或任何阻塞调用,完全由协程调度器进行调度。

Python 中以 asyncio 为依赖,使用 async/await 语法进行协程的创建和使用,如下 async 语法创建一个协程函数:

在判宽协程中除了普通函数的功能外最主要的作用就是:使用 await 语法等待另一个协程结束,这将挂起当前协程,直到另一个协程产生结果再继续执行:

asyncio.sleep() 是 asyncio 包内置的协程函数,这里模拟耗时的IO *** 作,上面这个协程执行到这一判埋句会挂起当前协程而去执行其他协程,直到sleep结束,当有多个协程任务时,这种切换会让它们的IO *** 作并行处理。

注意,执行一个协程函数并不会真正的运行它,而是会返回一个协程对象,要使协程真正的运行,需要将它们加入到事件循环中运行,官方建议 asyncio 程序应当有一个主入口协程,用来管理所有其他的协程任务:

在 Python3.7+ 中,运行这个 asyncio 程序只需要一句: asyncio.run(main()) ,而在 Python3.6 中,需要手动获取事件循环并加入协程任务:

事件循环就是一个循环队列,对其中的协程进行调度执行,当把一个协程加入循环,这个协程创建的其他协程都会自动加入到当前事件循环中。

其实协程对象也不是直接运行,而是被封装成一个个待执行的 Task ,大多数情况下 asyncio 会帮我们进行封装,我们也可以提前自行封装 Task 来获得对协程更多的控制权,注意,封装 Task 需要 当前线程有正在运行的事件循环 ,否则将引 RuntimeError,这也就是官方建议使用主入口协程的原因,如果在主入口协程之外创建任务就需要先手动获取事件循环然后使用底层方法 loop.create_task() ,而在主入口协程之内是一定有正在运行掘冲蚂的循环的。任务创建后便有了状态,可以查看运行情况,查看结果,取消任务等:

asyncio.create_task() 是 Python3.7 加入的高层级API,在 Python3.6,需要使用低层级API asyncio.ensure_future() 来创建 Future,Future 也是一个管理协程运行状态的对象,与 Task 没有本质上的区别。

通常,一个含有一系列并发协程的程序写法如下(Python3.7+):

并发运行多个协程任务的关键就是 asyncio.gather(*tasks) ,它接受多个协程任务并将它们加入到事件循环,所有任务都运行完成后会返回结果列表,这里我们也没有手动封装 Task,因为 gather 函数会自动封装。

并发运行还有另一个方法 asyncio.wait(tasks) ,它们的区别是:

并行分支为并行性流程控制程序的分支。

由两个及以上的分支程序组成的,必须同时执行各分支的程序,称为并行性流程控制程序,并行分明困支就是上述程序的分支。

流程控制指令会改变程序运行顺序,可能是运行不同位置的指令,或在二段程序中选一个运行。

扩展资料

流程控制指令的分类

1、继续运行位在不同位置的一段指令。

2、若特定条件成立时,运行一段指令,例如C语言的switch指令,是一种有条件分支指令。

3、运行一段指令若干次,直到特肆哗定条件成立为止,例如C语言的for指令,仍然可视为一种有条件分支指令。

4、运行位于不同位置的一段指令,但完成后会继续运行原来要运行的指令,包括子程序、协程及延续性。

5、停止程序,不运行任何指令。激雹念

参考资料

百度百科--流程控制

百度百科--并行控制

百度百科--三菱PLC


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12314976.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-24
下一篇 2023-05-24

发表评论

登录后才能评论

评论列表(0条)

保存