python协程

python之协程

醉酒当歌 提交于 2019-11-29 16:38:08
一、协程理论 1.1 协程产生的背景 之前我们学习了线程、进程的概念,了解了在操作系统中 进程是资源分配的最小单位,线程是CPU执行的最小单位。 随着我们对于效率的追求不断提高, 基于单线程来实现并发 又成为一个新的课题,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发。这样就可以节省创建线进程所消耗的时间。 本节我们就基于单线程来实现并发,首先我们要回顾一下并发的本质: 切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制) (1)该任务发生了阻塞 (2)该任务计算时间过长或有个更高级的程序替代它 ps:在介绍进程理论时,提及进程的三种执行状态,而线程才是执行单位,所以也可以将上图理解为线程的三种状态 注意点1 第二种情况本质上并不能提高效率,只是为了cpu能雨露均沾,实现看起来所有任务被“同时”执行,如果多个任务是纯计算的,单纯的切换反而会降低效率。 1.2 yield实现并发 我们通过yield验证,yield本身就是一种在单线程下可以保存任务运行状态的方法,我们来简单复习一下: #1 yiled可以保存状态,yield的状态保存与操作系统的保存线程状态很像,但是yield是代码级别控制的,更轻量级 #2 send可以把一个函数的结果传给另外一个函数,以此实现单线程内程序之间的切换 yield实现并发的缺点: (1

Python 协程

白昼怎懂夜的黑 提交于 2019-11-29 13:51:07
协程 进程 :操作系统中存在 线程 :操作系统中存在 协程 :是微线程 模块(greenlet) 协程不是一个真实存在的东西,是由程序员创造出来的 协程,是对一个线程分片,使得线程在代码块之间进行来回切换,而不是原来逐步执行。 单纯的协程是无用的,有时候而且会降低性能 示例代码: import greenlet def f1(): print(11) gr2.switch() print(22) gr2.switch() def f2(): print(33) gr1.switch() print(44) # 创建两个协程 gr1 = greenlet.greenlet(f1) gr2 = greenlet.greenlet(f2) gr1.switch() 协程存在的意义 单线程实现并发:如果遇到 IO操作 就会进行切换 遇到IO就切换 + 协程 == 牛逼起来了。。。 遇到IO就切换 实现: gevent模块 gevent模块(IO切换+协程) 安装: pip install gevent 示例代码: ########### 协程+IO切换 from gevent import monkey monkey.patch_all() # 以后代码中遇到IO就会执行greenlet的switch进行切换 import requests import gevent def get

Python与大数据之间有没有关系,图零说有的

痞子三分冷 提交于 2019-11-29 07:49:15
很多同学都知道python作为比较火的编程语言,人工智能需要它。除了人工智能,图零小编说,大数据也很需要它。 自从2004年以后,python的使用率呈线性增长。2011年1月,它被TIOBE编程语言排行榜评为2010年度语言。由于Python语言的简洁性、易读性以及可扩展性,在国外用Python做科学计算的研究机构日益增多,一些知名大学已经采用Python来教授程序设计课程。 数据就是资产。大数据工程师是现在十分火热、高薪的职位。做大数据开发和分析不仅要用到Java,Python也是较重要的语言。 那么,今天我们就来分析一下,Python之于大数据的意义和作用。 大数据现在互联网火热的一个名词,而和大数据关键词较紧密的相信就是Java和python了,在一年以前,Java大数据可能是很多培训机构的宣传标语。而到了2018年,python大数据则成为了潮流,无论是行业大佬亦或是培训机构都开始说python大数据了,这是为什么呢?如果你对大数据开发感兴趣,想系统学习大数据的话,可以加入大数据技术学习交流扣群:数字522+数字189+307,私信管理员即可免费领取开发工具以及入门学习资料 大数据为什么要学python?什么是大数据? 大数据是指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量

Python 基础之 I/O 模型

女生的网名这么多〃 提交于 2019-11-29 07:07:18
一、事件驱动模型介绍 1、传统的编程模式 例如:线程模式大致流程 开始--->代码A--->代码B--->代码C--->代码D--->......--->结果 每一个代码里是完成各种各样事情的代码,但编程者知道代码A,B,C,D...的执行顺序,唯一能够改变这个流程的是数据。输入不同的数据, 根据条件语句判断,流程或许就改为A--->B--->D...--->结束。 每一次程序运行顺序或许都不同,但它的控制流程是由输入数据和你编写的程序决定的。如果你知道这个程序当前的运行状态(包括输入 数据和程序本身),那你就知道接下来甚至一直到结束它的运行流程。 例如:事件驱动程序模型大致流程 开始--->初始化--->等待 与上面传统编程模式不同,事件驱动程序在驱动之后,就在那等待,等待什么呢?等待被事件触发。传统编程下也有“等待”,比如在 编代码D中,你定以了一个input(),你作为程序编写者是知道或者强制用户输入东西的,或许是数字,或许是文件名称,如果用户输入 错误,你还需要提醒他,并请他重新输入,事件驱动程序的等待则是完全不知道,也不强制用户输入或者干什么,只要某一事件 发生,那程序就会做出相应的“反应”。这些事件包括:输入信息、鼠标、敲击键盘上某个键还有系统内部定时器触发。 2、事件驱动模型 通常,我们写服务器处理模型的程序时,有一下几种模型: (1)每收到一个请求;创建一个新的进程

深入理解python的yield和generator

断了今生、忘了曾经 提交于 2019-11-29 01:44:54
原文发表在 我的博客主页 ,转载请注明出处 前言 没有用过的东西,没有深刻理解的东西很难说自己会,而且被别人一问必然破绽百出。虽然之前有接触过python协程的概念,但是只是走马观花,这两天的一次交谈中,别人问到了协程,顿时语塞,死活想不起来曾经看过的东西,之后突然想到了yield,但为时已晚,只能说概念不清,所以本篇先缕缕python的生成器和yield关键字。 什么是生成器 生成器是一个特殊的程序,可以被用作控制循环的迭代行为 生成器类似于返回值为数组的一个函数,这个函数可以接收参数,可以被调用,但是,不同于一般的函数会一次性返回包含了所有数值的数组,生成器一次只产生一个值,这样消耗的内粗数量大大减少,而且允许调用函数可以很快的开始处理前几个返回值。因此,生成器看起来像一个函数但是表现的却像一个迭代器。 python中的生成器 python提供了两种基本的方式。 生成器函数:也是用def来定义,利用关键字 yield 一次返回一个结果,阻塞,重新开始 生成器表达式:返回一个对象,这个对象只有在需要的时候才产生结果 下面详细讲解。 生成器函数 为什么叫生成器函数?因为他随着时间的推移生成了一个数值队列。一般的函数在执行完毕之后会返回一个值然后退出,但是生成器函数会自动挂起,然后重新拾起继续执行,他会利用 yield 关键字关起函数,给调用者返回一个值,同时保留了当前的足够多的状态

python多线程、多进程、协程笔记

倖福魔咒の 提交于 2019-11-28 23:57:57
import threading import time import multiprocessing import asyncio movie_list = ['斗破.avi', '复仇者联盟.mp4', '斗罗大陆.rmvb'] music_list = ['七里香.mp3', '美人鱼.mp3', 'xxx.obi'] movie_format = ['avi', 'mp4', 'rmvb'] music_format = ['mp3'] def play(playlist): for i in playlist: if i.split('.')[1] in movie_format: print('您现在正在收看:{}'.format(i)) time.sleep(2) elif i.split('.')[1] in music_format: print('您现在正在收听:{}'.format(i)) time.sleep(2) else: print('该文件格式不支持:{}'.format(i)) time.sleep(2) async def async_play(playlist): for i in playlist: if i.split('.')[1] in movie_format: print('您现在正在收看:{}'.format(i)) await

Python之并发编程(九)线程队列、Event事件、协程

回眸只為那壹抹淺笑 提交于 2019-11-28 22:53:51
线程队列、Event事件、协程 线程队列 先进先出示例: import queue #不需要通过threading模块里面导入,直接import queue就可以了,这是python自带的 #用法基本和我们进程multiprocess中的queue是一样的 q=queue.Queue() q.put('first') q.put('second') q.put('third') # q.put_nowait() #没有数据就报错,可以通过try来搞 print(q.get()) print(q.get()) print(q.get()) # q.get_nowait() #没有数据就报错,可以通过try来搞 ''' 结果(先进先出): first second third ''' 先进后出(Lifo堆栈)示例: import queue q=queue.LifoQueue() #队列,类似于栈,栈我们提过吗,是不是先进后出的顺序啊 q.put('first') q.put('second') q.put('third') # q.put_nowait() print(q.get()) print(q.get()) print(q.get()) # q.get_nowait() ''' 结果(后进先出): third second first ''' 优先级队列示例 import

百万年薪python之路 -- 并发编程之 协程

拜拜、爱过 提交于 2019-11-28 18:42:09
协程 一. 协程的引入 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态   cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制),一种情况是该任务发生了阻塞,另外一种情况是该任务计算的时间过长或有一个优先级更高的程序替代了它   协程本质上就是一个线程,以前线程任务的切换是由操作系统控制的,遇到I/O自动切换,现在我们用协程的目的就是较少操作系统切换的开销(开关线程,创建寄存器、堆栈等,在他们之间进行切换等),在我们自己的程序里面来控制任务的切换。     ps:在介绍进程理论时,提及进程的三种执行状态,而线程才是执行单位,所以也可以将上图理解为线程的三种状态 一:其中上图的第二种情况并不能提升效率,只是为了让cpu能够雨露均沾,实现看起来所有任务都被“同时”执行的效果,如果多个任务都是纯计算的,这种切换反而会降低效率。为此我们可以基于yield来验证。yield本身就是一种在单线程下可以保存任务运行状态的方法,我们来简单复习一下: #1 yiled可以保存状态,yield的状态保存与操作系统的保存线程状态很像,但是yield是代码级别控制的,更轻量级 #2 send可以把一个函数的结果传给另外一个函数,以此实现单线程内程序之间的切换

python_高级进阶(5)协程_事件

孤人 提交于 2019-11-28 18:20:51
线程queue 第一种、先进先出 import queue q = queue.Queue(3) q.put(1) q.put(2) q.put(3) q.put(4) print(q.get()) print(q.get()) print(q.get()) print(q.get(block=False)) q.get(timeout=2) # 阻塞2s 还没有值直接报错 结果: #1 #2 #3 ##第二种、后进先出 Lifo 堆栈 q = queue.LifoQueue(4) q.put(1) q.put(2) q.put('alex') q.put('太白') print(q.get()) print(q.get()) print(q.get()) print(q.get()) 结果: 太白 alex 2 1 第三种、优先级队列 q = queue.PriorityQueue(4) q.put((5, '元宝')) q.put((-2,'狗狗')) q.put((0, '李业')) print(q.get()) print(q.get()) print(q.get()) 结果: (-2, '狗狗') (0, '李业') (5, '元宝') 事件event 开启两个线程,一个线程运行到中间的某个阶段,触发另一个线程执行,两个线程增加了耦合性 版本一

Python网络编程——协程

你离开我真会死。 提交于 2019-11-28 16:19:45
协程的概念 协程,又称微线程,纤程,也称用户级线程,在不开辟线程的基础上实现多任务,也就是在单线程的情况下完成多任务,多个任务按照一定顺序交替执行的,通俗理解只要在def里面只看到一个yield关键字表示就是协程 协程也是实现多任务的一种方式 协程yield的代码实现 简单实现协程 import time# 定义协程def work1(): while True: print("work1...") time.sleep(1) yielddef work2(): while True: print("work2...") time.sleep(1) yieldif __name__ == '__main__': g1 = work1() g2 = work2() while True: next(g1) next(g2) 实现协程的第二种方式:greenlet greenlet介绍:为了更好使用协程来完成多任务,python中的greenlet模块对其封装,从而使得切换任务变得更加简单 首先使用pip安装greenlet模块: pip3 install greenlet greenlet的使用: # greentlet的使用import greenletimport timedef work1(): for i in range(10): print("work1") time