协程

异步IO框架:asyncio 中篇

隐身守侯 提交于 2019-12-11 12:49:49
上一节我们首先介绍了,如何创建一个协程对象. 主要有两种方法 通过 async 关键字, 通过 @asyncio.coroutine 装饰函数。 然后有了协程对象,就需要一个事件循环容器来运行我们的协程。其主要的步骤有如下几点: 将协程对象转为task任务对象 定义一个事件循环对象容器用来存放task 将task任务扔进事件循环对象中并触发 上一节,其实就只是讲了协程中的 单任务,我们就来看下,协程中的 多任务。 协程中的并发 协程的并发,和线程一样。举个例子来说,就好像 一个人同时吃三个馒头,咬了第一个馒头一口,就得等这口咽下去,才能去啃第其他两个馒头。就这样交替换着吃。 asyncio 实现并发,就需要多个协程来完成任务,每当有任务阻塞的时候就await,然后其他协程继续工作。 第一步,当然是创建多个协程的列表。 # 协程函数 async def do_some_work(x): print('Waiting: ', x) await asyncio.sleep(x) return 'Done after {}s'.format(x) # 协程对象 coroutine1 = do_some_work(1) coroutine2 = do_some_work(2) coroutine3 = do_some_work(4) # 将协程转成task,并组成list tasks = [

协程

妖精的绣舞 提交于 2019-12-11 00:34:22
windows: 当创建进程时,会将当前py文件由上到下重新执行一次,所以我们要将执行代码放在__ main __ 中。 linux: 在linux系统中,会直接复制一分代码去执行 这里有解决问题的办法: 国内:开源中国,CSDN, cnblods, https://www.v2ex.com/ 国外:Stack Overflow GIL: 全局解释器锁 Cpython的内存管理不是线程安全,在同一进程开启的多线程,同一时刻只能有一个线程执行,无法利用多核优势 GIL全局解释锁,本质上就是一把互斥锁,保证数据的安全 GIL全局解释器的优缺点: 1.优点: 保证数据的安全 2.缺点: 单个进程下,开启多个线程,牺牲执行效率,无法实现并行,只能实现并发 ,只能实现并发。 IO密集型,多线程 计算密集型,多进程 io密集型任务,每个任务4s 单核: 开启的线程比进程节省资源 多核: 多线程: 开启4个子线程:16s 多进程: 开启4个进程:16s + 申请开启资源消耗的时间 计算密集型任务,每个任务4s 单核: 开启线程比进程节省资源 多核: 多线程: 开启4个子线程:16s 多进程: 开启多个进程:4s 什么是协程? 进程:资源单位 线程:执行单位 协程: 单线程下实现并发 在io密集的情况下,使用协程能提高最高效率 ps:协程不是任何单位,只是一个个程序员臆想出来的东西

Python协程与Go协程的区别二

久未见 提交于 2019-12-10 20:33:38
写在前面 世界是复杂的,每一种思想都是为了解决某些现实问题而简化成的模型,想解决就得先面对,面对就需要选择角度,角度决定了模型的质量, 喜欢此UP主 汤质看本质 的哲学科普,其中简洁又不失细节的介绍了人类解决问题的思路,以及由概念搭建的思维模型对人类解决问题的重要性与限制.也认识到学习的本质就是: 认识获取(了解概念) -> 知识学习(建立模型) -> 技能训练(实践) 阅读也好, 学习也好, 妨碍我们「理解」的障碍主要有两个: 高度抽象的概念 「模型」无法关联现象 也就是说 概念明确 + 关系明确, 才能构成「模型」, 对照「现象」, 形成「理解」。 在理解编程知识时可以关键归纳为两点: 理解核心概念群+使用场景思考与故事化讲述 这里特别推荐码农翻身中大话编程式的科普: 码农翻身全年文章精华 并发模型 并发思想的一些探寻 并发之痛 Thread, Goroutine, Actor 中有较好的总结: 陈力就列, 不能者止 能干活的代码片段就放在线程里, 如果干不了活(需要等待, 被阻塞等), 就摘下来。通俗的说就是不要占着茅坑不拉屎, 如果拉不出来, 需要酝酿下, 先把茅坑让出来, 因为茅坑是稀缺资源。 要做到这点一般有两种方案: 异步回调方案 典型如NodeJS, 遇到阻塞的情况, 比如网络调用, 则注册一个回调方法(其实还包括了一些上下文数据对象)给IO调度器

2_进程_线程_协程

久未见 提交于 2019-12-10 16:09:20
协程定义 协程,又称微线程,纤程。英文名Coroutine。 首先我们得知道协程是啥?协程其实可以认为是比线程更小的执行单元。 为啥说他是一个执行单元,因为他自带CPU上下文。这样只要在合适的时机, 我们可以把一个协程 切换到另一个协程。 只要这个过程中保存或恢复 CPU上下文那么程序还是可以运行的。 协程和线程区别 线程切换从系统层面远不止保存和恢复 CPU上下文这么简单。 操作系统为了程序运行的高效性每个线程都有自己缓存Cache等等数据,操作系统还会帮你做这些数据的恢复操作。 所以线程的切换非常耗性能。但是协程的切换只是单纯的操作CPU的上下文,所以一秒钟切换个上百万次系统都抗的住。 协程拥有自己的寄存器上下文和栈,因此能保留上一次调用的状态。 协程例子 #coding=utf-8 import time def consumer():#有yield,是一个生成器 r="" while True: n=yield r #程序暂停,等待next()信号 # if not n: # return print('consumer <--%s..'%n) time.sleep(1) r='200 ok' def producer(c): next(c)#激活生成器c n=0 while n<5: n=n+1 print 'produer-->%s..'%n cr = c.send(n

协程

孤人 提交于 2019-12-09 19:27:41
目录 一 什么是协程? 二 协程介绍 三 Gevent 一 什么是协程? ​ 进程:资源单位 ​ 线程:执行单位 ​ 协程:单线程下实现并 在IO密集型的情况下,使用协程能提高最高效率 注意:协程不是任何单位,只是程序员YY出来的东西 手动实现 “遇到IO切换 + 保存状态“ 去欺骗操作系统,让操作系统误以为没有IO操作,将CPU的执行权限给你 cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制), 第一种情况是该任务发生了阻塞 第二种情况是该任务计算的时间过长或有一个优先级更高的程序替代了它 一:其中第二种情况并不能提升效率,只是为了让cpu能够雨露均沾,实现看起来所有任务都被“同时”执行的效果,如果多个任务都是纯计算的,这种切换反而会降低效率。 为此我们可以基于yield来验证。yield本身就是一种在单线程下可以保存任务运行状态的方法,我们来简单复习一下: #1 yiled可以保存状态,yield的状态保存与操作系统的保存线程状态很像,但是yield是代码级别控制的,更轻量级 #2 send可以把一个函数的结果传给另外一个函数,以此实现单线程内程序之间的切换 单纯的切换反而会降低运行效率 ''' 1、协程: 单线程实现并发 在应用程序里控制多个任务的切换+保存状态 优点: 应用程序级别速度要远远高于操作系统的切换 缺点:

GIL以及协程

左心房为你撑大大i 提交于 2019-12-09 19:25:08
GIL以及协程 一、GIL全局解释器锁 演示 ''' python解释器: - Cpython c语言 - Jpython java 1、GIL:全局解释器锁 - 翻译:在同一个进程下开启的多个线程,同一时刻只能有一个线程执行,因为Cpython的内存管理不是线程安全。 - GIL全局解释器锁,本质上就是一把互斥锁,保证数据安全 定义: In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython’s memory management is not thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.) 结论:在Cpython解释器中,同一个进程下开启的多线程,同一时刻只能有一个线程执行,无法利用多多核优势。 GIL全局解释器的优缺点: 优点: 保证数据的安全 缺点: 单个进程下,开启多个线程

协程

让人想犯罪 __ 提交于 2019-12-09 15:25:51
协程(Coroutine)本质上是一种用户态线程,不需要操作系统来进行抢占式调度,且在真正的实现中寄存于线程中,因此,系统开销极小,可以有效提高线程的任务并发性,而避免多线程的缺点。 goroutine是Go语言中轻量级线程实现,由Go运行时(runtime)管理。在一个函数调用前加上关键字go,这次调用就会在一个新的goroutine中并发执行,当被调用的函数返回时,这个goroutine也自动结束了。需要注意的是,如果这个函数有返回值,那么这个返回值就会被丢弃。 example package main import ( "fmt" ) func Add ( x , y int ) { z := x + y fmt . Println ( z ) } func main ( ) { for i := 0 ; i < 10 ; i ++ { go Add ( i , i ) } } 实际上面这段程序什么都不会输出,是什么原因让明明调用了十次函数的代码最终什么都没显示呢? 这里因为主函数启动了十个goroutine,然后返回,这个时候陈需就退出了,而被启动的goroutine还没来得执行,所以程序没有任何输出。 要让主函数等待所有goroutine退出后再返回,如何知道goroutine都退出了呢?这就引出了多个goroutine之间通信的问题。 在工程上,两种最常用的并发通信模型

Python自动化运维之高级函数

∥☆過路亽.° 提交于 2019-12-07 23:34:35
本帖最后由 陈泽 于 2018-6-20 17:31 编辑 一、协程 1.1协程的概念 协程,又称微线程,纤程。英文名Coroutine。一句话说明什么是线程:协程是一种用户态的轻量级线程。(其实并没有说明白~) 那么这么来理解协程比较容易:   线程是系统级别的,它们是由操作系统调度;协程是程序级别的,由程序员根据需要自己调度。我们把一个线程中的一个个函数叫做子程序,那么子程序在执行过程中可以中断去执行别的子程序;别的子程序也可以中断回来继续执行之前的子程序,这就是协程。也就是说同一线程下的一段代码执行着执行着就可以中断,然后跳去执行另一段代码,当再次回来执行代码块的时候,接着从之前中断的地方开始执行。 比较专业的理解是:   协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。因此:协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置。 1.2 协程的优缺点 协程的优点:   (1)无需线程上下文切换的开销,协程避免了无意义的调度,由此可以提高性能(但也因此,程序员必须自己承担调度的责任,同时,协程也失去了标准线程使用多CPU的能力)   (2)无需原子操作锁定及同步的开销   (3)方便切换控制流

TCP服务端-协程版(推荐)

放肆的年华 提交于 2019-12-07 16:35:28
利用gevent第三方库,实现协程。 通过协程实现一个服务端服务多个客户端,推荐使用协程版,因为协程比线程更加节省资源。 gevent安装命令: pip3 install gevent 注意:在安装gevent库之前,需要更新pip版本,只需要在终端窗口执行以下命令即可: python -m pip install --upgrade pip TCP服务端-协程版本: 1 import socket 2 import gevent 3 from gevent import monkey 4 5 # 打补丁 6 monkey.patch_all() 7 8 9 def handle_client_socket(new_socket, ip_port): 10 print("建立连接成功:", ip_port) 11 while True: 12 recv_data = new_socket.recv(1024) 13 if recv_data: 14 recv_data_decode = recv_data.decode("UTF-8") 15 print("服务端接收的数据为:", recv_data_decode) 16 else: 17 print("客户端下线了", ip_port) 18 break 19 # 8.使用新的套接字发送数据 20 send_data_input

爬虫04 /asyncio、selenium\\规避检测、动作链、无头浏览器

巧了我就是萌 提交于 2019-12-06 16:04:49
目录 爬虫04 /asyncio、selenium\规避检测、动作链、无头浏览器 1. 协程asyncio 2. aiohttp多任务异步爬虫 3. selenium的使用 4. 动作链 5. 12306模拟登录分析 6. selenium规避风险 7. 无头浏览器 总结: 爬虫04 /asyncio、selenium\规避检测、动作链、无头浏览器 1. 协程asyncio 协程基础 特殊的函数 就是async关键字修饰的一个函数的定义 特殊之处: 特殊函数被调用后会返回一个协程对象 特殊函数调用后内部的程序语句没有被立即执行 协程 对象。协程==特殊的函数。协程表示的就是一组特定的操作。 任务对象 高级的协程(对协程的进一步的封装) 任务对象==协程==特殊的函数 任务对象==特殊的函数 绑定回调: task.add_done_callback(task) 参数task:当前回调函数对应的任务对象 task.result():返回的就是任务对象对应的特殊函数的返回值 事件循环对象 创建事件循环对象 将任务对象注册到该对象中并且开启该对象 作用:loop可以将其内部注册的所有的任务对象进行异步执行 代码示例: import asyncio from time import sleep # 特殊的函数 async def get_request(url): print('正在下载:'