协程

day31 学习小结

浪子不回头ぞ 提交于 2019-12-02 06:42:59
目录 一、Event 事件 二、进程池与线程池 什么是进程池与线程池 进程池与线程池的作用 如何使用 三、协程 协程的目的 如何实现协程 一、Event 事件 Event事件的作用: 用来控制线程的执行。 由一些线程去控制另一些线程。 二、进程池与线程池 什么是进程池与线程池 进程池与线程池是用来控制当前程序允许创建(进程/线程)的数量。 进程池与线程池的作用 保证在硬件允许的范围内创建(进程/线程)的数量。 如何使用 三、协程 进程:资源单位 线程:执行单位 协程:在单线程下实现并发 注意:协程不是操作系统资源,他是程序起的名字,为让单线程能实现并发。 协程的目的 操作系统 多道技术,切换 + 保存状态 遇到IO CPU执行时间过长 协程: 通过手动模拟操作系统“多道技术”,实现 切换+保存状态 手动实现 遇到IO切换,欺骗操作系统误以为没有IO操作。 单线程 遇到IO,切换 + 状态保存 单线程 计算密集型,来回切换 + 保存状态时,反而效率更高 优点: ​ 在IO密集型的情况下,会提高效率。 缺点: ​ 若在计算密集型的情况下,会提高效率。 如何实现协程 切换 +保存状态 yield:保存状态 并发:切换 来源: https://www.cnblogs.com/bowendown/p/11735068.html

协程课堂小结day31

我怕爱的太早我们不能终老 提交于 2019-12-02 06:40:49
昨日回顾 GIL全局解释锁 python解释器 Cpython(C语言编写) Jpython(Java编写) Ppython(Python编写) GIL全局解释锁 基于CPython来研究全局解释器锁,因为CPython的内存线程不是安全的 GIL本质上是一个互斥锁 GIL是为了阻止同一个进程内多个线程同时执行(并行) GIL的存在就是为了保证线程安全 注意:多个线程过来执行,一旦遇到IO操作,就会立马释放GIL解释器锁,交给下一个先进来的线程 多线程的作用 计算密集型程序 在单核情况下,若一个任务需要10s 开启进程,消耗资源大,执行4个进程需要40s 开启线程,消耗资源小,执行4个线程需要40s 在多核情况下,若一个任务需要10s 开启进程,并行执行,效率较高,执行4个进程需要10s 开启线程,并发执行,效率较低,执行4个线程需要40s IO密集型程序 在单核情况下,若一个任务需要10s 开启进程,消耗资源大,执行4个进程需要40s 开启线程,消耗资源小,执行4个线程需要40s 在多核情况下,若一个任务需要10s 开启进程,并行执行,效率小于线程,因为遇到IO会立即切换CPU执行权限,执行4个进程需要10s = 开启进程的额外时间 开启线程,并发执行,效率高于进程,执行4个线程需要40s 死锁现象 死锁是指两个或两个以上的进程或线程在执行过程中

Python进程、线程、协程详解

ぐ巨炮叔叔 提交于 2019-12-02 06:37:41
进程与线程的历史 我们都知道计算机是由硬件和软件组成的。硬件中的CPU是计算机的核心,它承担计算机的所有任务。 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源的管理和分配、任务的调度。 程序是运行在系统上的具有某种功能的软件,比如说浏览器,音乐播放器等。 每次执行程序的时候,都会完成一定的功能,比如说浏览器帮我们打开网页,为了保证其独立性,就需要一个专门的管理和控制执行程序的数据结构——进程控制块。 进程就是一个程序在一个数据集上的一次动态执行过程。 进程一般由程序、数据集、进程控制块三部分组成。我们编写的程序用来描述进程要完成哪些功能以及如何完成;数据集则是程序在执行过程中所需要使用的资源;进程控制块用来记录进程的外部特征,描述进程的执行变化过程,系统可以利用它来控制和管理进程,它是系统感知进程存在的唯一标志。 在早期的操作系统里,计算机只有一个核心,进程执行程序的最小单位,任务调度采用时间片轮转的抢占式方式进行进程调度。每个进程都有各自的一块独立的内存,保证进程彼此间的内存地址空间的隔离。 随着计算机技术的发展,进程出现了很多弊端,一是进程的创建、撤销和切换的开销比较大,二是由于对称多处理机(对称多处理机(SymmetricalMulti-Processing)又叫SMP,是指在一个计算机上汇集了一组处理器(多CPU),各CPU之间共享内存子系统以及总线结构

Day10 - Python协程、异步IO、redis缓存、rabbitMQ队列

丶灬走出姿态 提交于 2019-12-02 06:25:32
引子 到目前为止,我们已经学了网络并发编程的2个套路, 多进程,多线程,这哥俩的优势和劣势都非常的明显,我们一起来回顾下 协程 协程,又称微线程,纤程。英文名Coroutine。一句话说明什么是线程: 协程是一种用户态的轻量级线程 。 协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。因此: 协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置。 协程的好处: 无需线程上下文切换的开销 无需原子操作锁定及同步的开销   "原子操作(atomic operation)是不需要synchronized",所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (切换到另一个线程)。原子操作可以是一个步骤,也可以是多个操作步骤,但是其顺序是不可以被打乱,或者切割掉只执行部分。视作整体是原子性的核心。 方便切换控制流,简化编程模型 高并发+高扩展性+低成本:一个CPU支持上万的协程都不是问题。所以很适合用于高并发处理。 缺点: 无法利用多核资源:协程的本质是个单线程,它不能同时将 单个CPU 的多个核用上,协程需要和进程配合才能运行在多CPU上

Event事件与协程

这一生的挚爱 提交于 2019-12-02 06:23:46
1.Event事件 Event事件的作用: - 用来控制线程的执行. - 由一些线程去控制另一些线程. 2.进程池与线程池 1)什么是进程池与线程池? 进程池与线程池是用来控制当前程序允许创建(进程/线程)的数量. 2)进程池与线程池的作用: 保证在硬件允许的范围内创建 (进程/线程) 的数量. 3.协程 - 进程: 资源单位 - 线程: 执行单位 - 协程: 在单线程下实现并发 注意: 协程不是操作系统资源,他是程序起的名字,为让单线程能实现并发. 协程的目的: - 操作系统: 多道技术, 切换 + 保存状态 1) 遇到IO 2) CPU执行时间过长 - 协程: 通过手动模拟操作系统 "多道技术",实现 切换 + 保存状态 1)手动实现 遇到IO切换, 欺骗操作系统误以为没有IO操作. - 单线程下遇到IO, 切换 + 保存状态 - 单线程下计算密集型, 来回切换 + 保存状态是,反而效率更低 优点: 在IO密集型的情况下, 会提高效率. 缺点: 若在计算密集型的情况下, 来回切换, 反而效率更低. 4.TCP服务端实现协程 # 服务单 from gevent import monkey monkey.patch_all() import socket from gevent import spawn server = socket.socket() server.bind((

协程

混江龙づ霸主 提交于 2019-12-02 06:18:28
Event 用来控制线程的执行 有一些线程去控制另一些线程 Event对象包含一个可由线程设置的信号标志,它允许线程等待某些事件的发生 初始情况下,Event对象中的信号标志被设置为假。如果有线程等待一个Event对象, 而这个Event对象的标志为假,那么这个线程将会被一直阻塞直至该标志为真。 一个线程如果将一个Event对象的信号标志设置为真,它将唤醒所有等待这个Event对象的线程 线程特性: 每个线程都是独立运行且状态不可预测 from threading import Event event.isSet() # 判断event 的状态值, event.wait() # 当event.isSet() == Fadlse,将阻塞线程 event.set(): 设置event的状态值为True,所有阻塞池的线程激活进入就绪状态, 等待操作系统调度; event.clear():恢复event的状态值为False Timer : --定时器 from threading import Timer def hello(): print('hello world') t = Timer(9,hello) # 时间 t.start() 线程池 / 进程池: 问题 : 服务的开启的进程数或线程数都会随着并发的客户端数目地增多而增多,这会对服务端主机带来巨大的压力,甚至于不堪重负而瘫痪

协程(用户态线程)

霸气de小男生 提交于 2019-12-02 05:21:30
协程(用户态线程) 文章目录 协程(用户态线程) 协程 对比线程 多线程一定快吗? 并发和上下文切换 协程的艺术 演示 总结 协程 首先什么是协程?有人认为进程下有线程,线程管理着协程.其实这并不对 协程是一种用户态线程.它比线程更加轻量并且协程对于操作系统是并不可见的. 也就是说操作系统看不见协程 同一时刻一个CPU只会执行一个协程. 比如交给协程去执行的代码你可以理解为一个个提交的任务 对比线程 那什么是线程? 线程是进程的一个实体,是CPU调度和分派的基本单位.线程是程序中一个单一的顺序控制流程。进程内有一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指令运行时的程序的调度单位。 创建一个线程每个线程都有自己的TCB都有自己的堆栈.创建一个线程是有很大的花销的 也就是说一台服务器的资源总是有限的,你不可能无休止的去开线程(总有一天你会把内存占完) 默认创建一个线程的大小是1MB(取决于实现)也就是说4G的内存 最多只能创建4096个 但是很多时候我们创建的一个线程用不了这么多内存空间 线程的平均内存空间利用率是很低的 那可能有很多人写过这样的一个程序. 是一个基于Socket聊天的程序.大部分人是这样做的来一个Socket以后为其开一个线程工作.这样小程序的时候貌似没有什么问题 但是只要程序一大可能计算机资源就被分配光了.

swoole与php协程实现异步非阻塞IO开发

不问归期 提交于 2019-12-02 03:26:46
“协程可以在遇到阻塞的时候中断主动让渡资源,调度程序选择其他的协程运行。从而实现非阻塞IO” 然而php是不支持原生协程的,遇到阻塞时如不交由异步进程来执行是没有任何意义的,代码还是同步执行的,如下所示: function foo() { $db=new Db(); $result=(yield $db->query()); yield $result; } 上面的数据库查询操作是阻塞的,当调度器调度该协程到这一步时发现执行了阻塞操作,此时调度器该怎么办?选择其余协程执行?那该协程的阻塞操作又该何时执行,交由谁执行呢?所以说在php协程中抛开异步调用谈非阻塞IO属于耍流氓。 而swoole的异步task提供了一个实现异步的解决方案,关于swoole_task可以参考官方文档 核心功能实现 将一次请求形成一个协程 首先创建一个swoole_server并设置回调 class HttpServer implements Server { private $swooleHttpServer; public function __construct(\swoole_http_server $swooleHttpServer) { $this->swooleHttpServer = $swooleHttpServer; } public function start() { $this-

python使用gevent实现协程

余生长醉 提交于 2019-12-02 02:41:44
gevent是一个基于协程的python网络库,在遇到IO阻塞时,程序会自动进行切换,可以让我们用同步的方式写异步IO代码。 # coding:utf8 import requests import gevent from gevent import monkey monkey.patch_all() # 用于将标准库中大部分阻塞式调用修改为协作式运行 def fetch(url): print("get: {}".format(url)) response = requests.get(url).content print("{}: {}".format(url, len(response))) if __name__ == "__main__": gevent.joinall([ gevent.spawn(fetch, "https://stackoverflow.com/"), gevent.spawn(fetch, "https://www.douban.com"), gevent.spawn(fetch, "https://www.github.com") ]) 结果为: >>> get: https://stackoverflow.com/ >>> get: https://www.douban.com >>> get: https://www.github.com >

异步编程学习

独自空忆成欢 提交于 2019-12-02 00:31:52
原文章来源于: https://mp.weixin.qq.com/s?__biz=MzIxMjY5NTE0MA==&mid=2247483720&idx=1&sn=f016c06ddd17765fd50b705fed64429c原项目GitHub: https://github.com/denglj/aiotutorial原文章写得很精彩,但有些代码还是可以优化下的。而且这文章一直只有上篇,可惜了。接下来按个人见解,从代码角度解析下这篇文章:前提知识讲解:1、计算机资源:常分为CPU资源、内存资源、硬盘资源和网络资源2、进程阻塞:正在运行的程序,由于自身某个模块需要使用硬盘或网络I/O资源等,而系统又未及时响应,导致进程处于待机状态,直至等待事件作出回应后才会被唤醒。3、进程非阻塞:同理,在获取某些资源时,不会等待结果响应,而是继续处理其他模块。我们以socket为例,如下可获取阻塞与非阻塞两种编程 import socket sock = socket.socket() socket.setblocking(True) # 默认就是阻塞。即套接字 建立连接/发送请求/接受请求 的时候,是阻塞的。socket.setblocking(False) # 设置为非阻塞,即上述请求过程不会阻塞,而是继续处理其他模块。 使用原生asyncio编写异步程序: 在此代码中