协程

IO多路复用,协程

倖福魔咒の 提交于 2019-12-01 13:22:26
https://www.cnblogs.com/wangjun187197/p/9642429.html Python之路--协程/IO多路复用 引子:   之前学习过了,线程,进程的概念,知道了在操作系统中进程是资源分配的最小单位,线程是CPU调度的最小单位.按道理来说我们已经算是把CPU的利用率提高很多了.但是我们知道无论是创建多进程还是创建多线程来解决问题,都要消耗一定的时间来创建进程,创建线程,以及管理他们之间的切换.   随着我们对于效率的最求不断提高,基于单线程来实现并发又成为一个新的课题.即只用一个主线程的情况下实现并发.这样就可以节省创建线程进程所消耗的时间.   并发的本质: 切换+保存状态   cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制),一种情况是任务发生了阻塞,另外一种情况是该任务计算时间过长      对于单线程下,我们不可避免程序中出现io操作,但如果我们能在自己的程序中(即用户程序级别,而非操作系统级别)控制单线程下的多个任务能在一个任务遇到io阻塞时就切换到另外一个任务去计算,这样就保证了该线程能够最大限度地处于就绪态,即随时都可以被cpu执行的状态,相当于我们在用户程序级别将自己的io操作最大限度地隐藏起来,从而可以迷惑操作系统,让其看到:该线程好像是一直在计算,io比较少

Swoole 协程工作池 swoole-co-pool

心已入冬 提交于 2019-12-01 13:08:37
介绍 Swoole 协程工作池,它可以限定你的同时工作协程数量,并且减少协程频繁创建销毁的损耗。 原理 事先定好协程数量和工作队列长度,将所有工作协程事先创建好。 使用 Swoole\Coroutine\Channel 实现工作队列。 在每个工作协程中, Swoole\Coroutine\Channel->pop() 。一旦有新的任务 push 进队列,就会有一个工作协程被唤醒。 安装 在您的composer.json中加入配置: 然后执行 composer update 命令。 使用 代码示例 详见 test/test.php 来源: https://www.cnblogs.com/programmer123/p/11686889.html

Python连载42-异步协程函数

限于喜欢 提交于 2019-12-01 10:44:05
一、 asyncio 1.python3.4开始引入标准库之中,内置对异步io的支持 2.asyncio本身是一个消息循环 3.步骤: (1)创建消息循环 (2)把协程导入 (3)关闭 4.举例: import threading #引入异步io包 import asyncio #使用协程 @asyncio.coroutine def hello(): print("Hello World!(%s)"%threading.current_thread()) print("Start......(%s)"%threading.current_thread()) yield from asyncio.sleep(5) print("Done.....(%s)"%threading.current_thread()) print("Hello again!(%s)"%threading.current_thread()) #启动消息循环 loop = asyncio.get_event_loop() #定义任务 tasks = [hello(),hello()] #asyncio使用wait等待task执行完毕 loop.run_until_complete(asyncio.wait(tasks)) #关闭消息循环 loop.close() 二、asyncio and await 1

爬虫4:单线程+多任务的异步协程,selenium的基本使用,基于js加密和混淆的案列

谁都会走 提交于 2019-12-01 08:40:44
1.单线程+多任务的异步协程 特殊函数: 如果一个函数的定义被asyncio修饰后,则该函数就成了一个特殊的函数。 协程: 就是一个协程对象。特殊函数调用的返回就是协程对象。 特殊函数被调用后,函数内部的实现语句不会被立即执行,然后该函数调用就会返回一个协程对象。 特殊函数的调用的返回 == 协程对象。 任务对象(只是在爬虫里面才会有任务对象): 其实就是对协程对象的进一步封装。 结论: 任务对象,就是一个高级的协程对象 任务对象 == 高级的协程对象 == 特殊函数调用的返回 为什么要使用任务对象? 因为任务对象可以绑定回调函数,协程对象和特殊的函数都没有回调函数 事件循环对象:是整个异步中的重要操作,没有它就实现不了异步 作用:将其内部注册的任务对象进行异步执行。  使用单线程+多任务的异步协程的编码流程    1.定义特殊函数    2.创建协程对象    3.封装任务对象    4.创建事物循环对象    5.将任务对象注册到事物循环对象并且开启循环对象 2.代码实现 import asyncio import time from time import sleep start = time.time() # 函数调用 async def get_request(url): # 加上async之后,在调用特殊函数的时候,里面的代码不会被执行,但是会返回一个coroutine

python协程 示例

£可爱£侵袭症+ 提交于 2019-12-01 07:26:07
协程 1.协程 又称微线程 是一种轻量级线程 携程有自己的寄存器 上下文 和栈 携程能保留上一次调用时的状态 2.协程优点和缺点 : 1.无需线程上下文切换的开销 2.无需原子操作锁定及同步的开销 3.高并发 高扩展性 低成本 缺点: 1.无法利用多核资源 2.阻塞操作会阻塞整个程序 python利用 yield来达到携程效果,:先看下 关于yield的两个用法 ( yield from 是python3 的方法) def aa(): for i in 'ab': yield i for i2 in range(0, 3): yield i2 print list(aa()) 》》》 ['a', 'b', 0, 1, 2] def bb(): yield from 'ab' yield from range(3) print (list(bb())) 》》》 ['a', 'b', 0, 1, 2] 利用yield 来写一个经典的生产 消费者: def consumer(name):# 消费者 print("--->starting") while True: new_baozi = yield print("[%s] is eating baozi %s" % (name, new_baozi)) def producer(): # r = con.__next__() r =

爬虫—使用协程构建高性能爬虫

╄→гoц情女王★ 提交于 2019-12-01 07:19:15
使用协程构建高性能爬虫 一、简介   在执行一些 IO 密集型任务的时候,程序常常会因为等待 IO 而阻塞。比如在网络爬虫中,如果我们使用 requests 库来进行请求的话,如果网站响应速度过慢,程序一直在等待网站响应,最后导致其爬取效率是非常非常低的。为了解决这类问题,本文就来探讨一下 Python 中异步协程来加速的方法,此种方法对于 IO 密集型任务非常有效。如将其应用到网络爬虫中,爬取效率甚至可以成倍地提升。本文使用 async/await 来实现,需要 Python 3.5 及以上版本。 二、概念介绍 1.阻塞   程序未得到所需计算资源时被挂起的状态。程序在等待某个操作完成期间,自身无法继续干别的事情,则称该程序在该操作上是阻塞的。阻塞形式有:网络 I/O 阻塞、磁盘 I/O 阻塞、用户输入阻塞等。包括 CPU 切换上下文时,多核 CPU 则正在执行上下文切换操作的核不可被利用。 2.非阻塞   程序在等待某操作过程中,自身不被阻塞,可以继续运行干别的事情,则称该程序在该操作上是非阻塞的。非阻塞的存在是因为阻塞存在,正因为某个操作阻塞导致的耗时与效率低下,我们才要把它变成非阻塞,以提高效率。 3.同步   不同程序单元为了完成某个任务,在执行过程中需靠某种通信方式以协调一致,称这些程序单元是同步执行的。例如购物系统中更新商品库存,需要用“锁”作为通信信号

go语言协程安全map

送分小仙女□ 提交于 2019-12-01 07:00:53
前言: 在go语言中 map 是很重要的数据结构。Map 是一种无序的键值对的集合。Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值。问题来了,这么安逸的 数据结构,它不是协程安全的 !当多个 协程同时对一个map 进行 读写时,会抛出致命错误。总结一下 想要 做到 协程安全 map 一共有以下三种方法。 1.map + 锁 这是最常见的一种操作,当要对 map操作的时候就加锁,其他的 协程就等待。下面是代码示例: package util import "sync" type SafeMap struct { Data map[string]interface{} Lock sync.RWMutex } func (this *SafeMap) Get(k string) interface{} { this.Lock.RLock() defer this.Lock.RUnlock() if v, exit := this.Data[k]; exit { return v } return nil } func (this *SafeMap) Set(k string, v interface{}) { this.Lock.Lock() defer this.Lock.Unlock() if this.Data == nil { this

3-1 协程介绍

送分小仙女□ 提交于 2019-12-01 06:48:58
一 引子 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制),一种情况是该任务发生了阻塞,另外一种情况是该任务计算的时间过长或有一个优先级更高的程序替代了它 ps:在介绍进程理论时,提及进程的三种执行状态,而线程才是执行单位,所以也可以将上图理解为线程的三种状态 一:其中第二种情况并不能提升效率,只是为了让cpu能够雨露均沾,实现看起来所有任务都被“同时”执行的效果,如果多个任务都是纯计算的,这种切换反而会降低效率。为此我们可以基于yield来验证。yield本身就是一种在单线程下可以保存任务运行状态的方法,我们来简单复习一下: 1 yiled可以保存状态,yield的状态保存与操作系统的保存线程状态很像,但是yield是代码级别控制的,更轻量级 2 send可以把一个函数的结果传给另外一个函数,以此实现单线程内程序之间的切换 单纯地切换反而会降低运行效率 #串行执行 import time def consumer(res): '''任务1:接收数据,处理数据''' pass def producer(): '''任务2:生产数据''' res=[] for i in range(10000000):

在 PHP 中使用 Promise + co/yield 协程

扶醉桌前 提交于 2019-12-01 06:21:49
为什么需要异步方式 一个函数执行之后,在它后面顺序编写的代码中,如果能够直接使用它的返回结果或者它修改之后的引用参数,那么我们通常认为该函数是同步的。 而如果一个函数的执行结果或者其修改的引用参数,需要通过设置回调函数或者回调事件的方式来获取,而在其后顺序编写的代码中无法直接获取的话,那么我们通常认为这样的函数是异步的。 PHP 提供的大部分函数都是同步的。通常我们会有一个误解,那就是容易把同步和阻塞当成同一个概念,但实际上同步代码不一定都是阻塞的,只是同步代码对阻塞天然友好,当同步代码和阻塞结合时,代码通常是简单易懂的。 阻塞带来的问题是当前线程(或进程)会陷入等待,一直等到阻塞结束,这样就会造成线程(或进程)资源的浪费。所以,通常认为阻塞是不够高效的。 但是如果要编写非阻塞代码,使用同步方式会变得有些复杂,且不够灵活。同步方式的非阻塞代码通常会使用 select 模式,例如 curl_multi_select , stream_select , socket_select 等就是 PHP 中提供的一些典型的 select 模式的函数。 我们说它复杂且不够灵活是有理由的,例如使用上面的 select 模式编写同步的非阻塞代码时,我们需要先构造一个并发任务的列表,之后手动构造循环来执行这些并发的任务,在循环开始之后,虽然这几个任务可以并发

如何在微信小程序中使用 Hprose(三)

家住魔仙堡 提交于 2019-12-01 06:21:39
Hprose 技术交流群:48855729 如何在微信小程序中使用 Hprose 如何在微信小程序中使用 Hprose(二) 书接上回,上一回中我们讲到 Hprose 提供的协程可以让 Hprose 的异步调用同步化。但是在最后的例子中,有一个小的细节,不知道你有没有注意到,就是程序的最后,我们使用了这样的代码: this.setData({ userInfo: yield app.getUserInfo }); 将原本复杂的通过异步调用来设置 setData 的过程同步化了。这是因为 hprose 提供了的协程,可以 yield 单参数回调方法的函数,并将回调方法的参数作为该 yield 调用的返回值。从而避免了 that 和 this 之间的转换,也避免了写回调函数。 但是 hprose 的所提供对协程的支持不止于此,hprose 还将 wx 的所有 API 都封装到了 hprose.wx 下面,将需要使用回调方式的 API 封装成了返回 promise 对象的 API,通过这种封装,所有这些 API,就都可以使用 co/yield 方式同步调用了。 例如微信官方例子中,上传文件的例子是这样的: wx.chooseImage({ success: function(res) { var tempFilePaths = res.tempFilePaths wx