python协程

python学习笔记之---多进程

我与影子孤独终老i 提交于 2019-12-04 05:42:27
首先,思考多进程、多线程、协程的区别? 其次,什么时候该用哪种模式? 进程:一个程序在计算机里面的一次运行。 线程:进程中调度执行的最小单位。 多进程:利用多核cpu,硬件的计算能力变强了。 程序的计算要求比较高的时候。 多线程:一核cpu,硬件的计算能力变弱了。 不是强调计算能力,而是强调多io操作的时候。(什么是IO?输入,输出:从键盘接收一个东西叫输入,打印一个东西叫输出) 多个线程之间做切换,比协程的切换效率要低一些。 协程: 本质是单线程,比多线程的效率高 单线程来实现不同任务的切换,是任务本身来实现的。 多io操作。 多进程编程会比多线程编程麻烦:因为多进程之间是无法共享一个变量的,多线程之间可以共享变量(同一个进程里)的使用,比较麻烦。 什么时候该用哪种模式呢? 计算密集型的任务时使用多进程,多核cpu计算效率更高 做多io操作的时候用线程或者协程都可以,但是对于多io来说协程的效率比多线程更高一些,不过同时协程的复杂度也比多线程更高一些 区别是什么? 线程必须运行在进程里面,一个进程至少有一个线程。 进程是操作系统分配资源的最小单位。 一个进程中的不同线程,会共用一个进程中的资源。 并发和并行什么区别: 并发:一起执行,并不一定是在某一时刻就同时执行 并行:在同一时刻执行。 多进程、多线程、协程都是用来提升并发性的。 同步:注册和登录,必须按同步是按顺序执行

python--协程知识初识

余生颓废 提交于 2019-12-04 00:58:08
线程和进程的操作是由程序触发系统接口,最后的执行者是系统;协程的操作则是程序员。 协程存在的意义:对于多线程应用,CPU通过切片的方式来切换线程间的执行,线程切换时需要耗时(保存状态,下次继续)。协程,则只使用一个线程,在一个线程中规定某个代码块执行顺序。 协程的适用场景:当程序中存在大量不需要CPU的操作时(IO),适用于协程; event loop是协程执行的控制点, 如果你希望执行协程, 就需要用到它们。 event loop提供了如下的特性:   1、注册、执行、取消延时调用(异步函数)   2、创建用于通信的client和server协议(工具)   3、创建和别的程序通信的子进程和协议(工具)   4、把函数调用送入线程池中 协程示例一: 1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 """ 4 协程示例 5 """ 6 import asyncio 7 8 async def test1(): 9 print("test1, starting") 10 await test2() 11 print("test1, ending") 12 13 async def test2(): 14 print("test2 start") 15 16 loop = asyncio.get_event_loop()

day13学python 协程+事件驱动

亡梦爱人 提交于 2019-12-03 23:36:48
day13学python 协程+事件驱动 协程+事件驱动 协程 (微线程)--用处多,重点   当调度切换时 靠寄存器上下文和栈保存 要使用时再调用(即可不会因io传输数据卡壳 从而耗时无法继续进行)实现并行 优缺点: 优点: 1 无需同线程上下文切换 消耗cpu 2 修改数据无需加锁(协程都是单线程串行 无需加锁) 3 cpu支持大量协程 缺点: 1无法调用多核资源(本身是单线程)  --指的是cpu只用单核运作 ============================================================================================================ 接下来介绍两种协程切换的 模板与方法 1.greenlet协程切换(手动挡) 2.gevent协程切换(自动挡) greenlet 模板(手动切换) import greenlet def test1(): print(1) gr2.switch() print(3) gr2.switch() def test2(): print(2) gr1.switch() print(4) if __name__=='__main__': gr1=greenlet.greenlet(test1) #启动协程 函数名作为参数 gr2=greenlet.greenlet

python-进程&线程&协程

喜夏-厌秋 提交于 2019-12-03 15:30:01
老规矩,先理解概念 冯诺依曼体系:   输入设备:键盘、鼠标   存储器:内存   输出设备:显示器、投影仪、打印机 程序:一个包含了代码片被编译后的文件 进程:系统通过解析程序文件 加载到内存中 的对象,进程是 资源 分配和调度的 基本单位 (分配cpu, 分配内存大小,它由系统进行调度),进程中包含 指令 (if, for…)、 数据 (变量,函数…)、 线程 (他也是线程的容器),他是操作系统结构的基础。 线程:进程中真正干活的人,线程是 资源调度 的最小单元,是 程序 执行流的最小单元,线程中包含 线程id 、 当前指令的指针 (线程会切换,再次运行还能从阻塞的位置继续), 寄存器集合 (线程切换,这个线程执行的结果进行保存)、 堆栈 (栈是先进后出,执行一个函数要先生成函数对象->函数压栈->变量引用压栈->调用函数->弹出栈顶,线程执行的其实也就是函数中大代码片,从Thread的target参数就能看出来,它接收的是一个函数或则方法) 进程 注释: 1:每一个进程都认为自己独占所有的计算机硬件资源() 2: 进程间不共享数据(这里就要解决进程间通信的问题) 线程 注释:上边已经大致讲了一下线程,这里再说一下线程的特点 1:一个进程中可以有多个线程,同一个进程中的线程共享数据资源(这里需要学好python中的作用域,因为python是用作用域来控制进程中的资源

Python核心技术与实战 笔记

独自空忆成欢 提交于 2019-12-03 06:30:24
基础篇 Jupyter Notebook 优点 整合所有的资源 交互性编程体验 零成本重现结果 实践站点 Jupyter 官方 Google Research 提供的 Colab 环境 安装 运行 列表与元组 列表和元组,都是 一个可以放置任意数据类型的有序集合。 l = [1, 2, 'hello', 'world'] # 列表中同时含有 int 和 string 类型的元素 l [1, 2, 'hello', 'world'] tup = ('jason', 22) # 元组中同时含有 int 和 string 类型的元素 tup ('jason', 22) 列表是动态的,长度大小不固定,可以随意地增加、删减或者改变元素 (mutable) 元组是静态的,场地大小固定,无法增加删除或者改变 (immutable) 都支持负数索引; 都支持切片操作; 都可以随意嵌套; 两者可以通过 list() 和 tuple() 函数相互转换; 列表和元组存储方式的差异 由于列表是动态的,所以它需要存储指针,来指向对应的元素。增加/删除的时间复杂度均为 O(1)。 l = [] l.__sizeof__() // 空列表的存储空间为 40 字节 40 l.append(1) l.__sizeof__() 72 // 加入了元素 1 之后,列表为其分配了可以存储 4 个元素的空间 (72 -

python的协程例子:每次输入一个数字,然后计算出所有输入数字的平均值

空扰寡人 提交于 2019-12-03 04:31:19
#!/usr/bin/env python3 def mean_x(): s = 0.0 n = 0 while True: s += yield n+=1 print("s =", s, "n=", n) print("mean = ", s/n) x = mean_x() next(x) while True: print("please input number...") x.send(float(input())) 能写出类似的例子,就是理解协程了。 来源: CSDN 作者: 未济2019 链接: https://blog.csdn.net/u011539200/article/details/81039846

python-使用协程下载妹子图片

流过昼夜 提交于 2019-12-03 04:10:29
import urllib.requestimport geventimport gevent.monkeygevent.monkey.patch_all()def downloader(img_name, img_url): req = urllib.request.urlopen(url=img_url) img_content = req.read() with open(img_name, 'wb') as f: f.write(img_content)def main(): gevent.joinall([gevent.spawn(downloader, '1.jpg', 'https://rpic.douyucdn.cn/live-cover/roomCover/2019/09/05/6668ef0693e932a3fec8994d8bfdcbaf_big.jpg'), gevent.spawn(downloader, '2.jpg', 'https://rpic.douyucdn.cn/live-cover/appCovers/2019/10/19/7605123_20191019184322_small.jpg') ])if __name__ == '__main__': main() 来源: https://www.cnblogs.com/fuyouqiang/p

python-协程gevent的使用

白昼怎懂夜的黑 提交于 2019-12-03 03:56:27
import geventfrom gevent import monkeyimport timeimport random# 有耗时操作时需要monkey.patch_all() # 将程序中用到的耗时操作代码,换为 gevent 中自己实现的模块def work(name): for i in range(10): print(name, i) time.sleep(random.random())gevent.joinall([ gevent.spawn(work, 'work1'), gevent.spawn(work, 'work2')])# 等价于'''g1 = gevent.spawn(work, 'work1')g2 = gevent.spawn(work, 'work2')g1.join()g2.join()''' 来源: https://www.cnblogs.com/fuyouqiang/p/11775772.html

Python迭代器,生成器和协程

一曲冷凌霜 提交于 2019-12-03 03:24:19
Python迭代器,生成器和协程 基础概念 在学习Python协程之前首先需要了解Python生成器的概念,而生成器又是一种特殊的迭代器,所以从迭代器开始学习。 Python迭代器(Iterator) 首先了解可迭代对象(interable), 具体来说就是遵循了可迭代协议的对象,比如查看Python list内置类的源码可以发现它实现了 iter ()函数,所以list是一个可迭代对象,当然还有dict, str, set等等。 可迭代协议:含 iter ()方法。且可迭代对象中的 iter ()方法返回的是一个对应的迭代器。(如list对应的迭代器就是list_iterator) 而迭代器与可迭代对象不同的是,迭代器对象不仅需要实现 iter ()方法,它还需要实现 next ()方法,即迭代器协议,事实上任何实现了 iter ()和 next ()方法的类对象都可以是迭代器对象。 迭代器协议: - 含 iter ()方法。且方法返回的Iterator对象本身 - 含 next ()方法,每当 next ()方法被调用,返回下一个值,直到没有值可以访问,这个时候会抛出stopinteration的异常。 此外迭代器含有两个基本的方法iter()和next(), iter()方法的作用是返回一个迭代器对象,当我们使用迭代器的next()方法显式获取元素的时候

Python之路(第四十七篇) 协程

此生再无相见时 提交于 2019-12-03 02:45:09
一、协程介绍 协程:是单线程下的并发,又称微线程,纤程。英文名Coroutine。一句话说明什么是线程: 协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的。 协程相比于线程,最大的区别在于,协程不需要像线程那样来回的中断切换,也不需要线程的锁机制,因为线程中断或者锁机制都会对性能问题造成影响,所以协程的性能相比于线程,性能有明显的提高,尤其在线程越多的时候,优势越明显。 协程的好处: 无需线程上下文切换的开销 无需原子操作锁定及同步的开销 "原子操作(atomic operation)是不需要synchronized",所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (切换到另一个线程)。原子操作可以是一个步骤,也可以是多个操作步骤,但是其顺序是不可以被打乱,或者切割掉只执行部分。视作整体是原子性的核心。 方便切换控制流,简化编程模型 高并发+高扩展性+低成本:一个CPU支持上万的协程都不是问题。所以很适合用于高并发处理。 缺点: 无法利用多核资源:协程的本质是个单线程,它不能同时将单个 CPU 的多个核用上,协程需要和进程配合才能运行在多 CPU 上.当然我们日常所编写的绝大部分应用都没有这个必要,除非是 CPU 集型应用。 进行阻塞(Blocking)操作(如IO时)会阻塞掉整个程序