同步是CPU自己主动查看IO操作是否完成,异步是IO操作完成后发出信号通知CPU(CPU是被通知的)

阻塞与非阻塞的区别在于发起IO操作之后,CPU是等待IO操作完成再进行下一步操作,还是不等待去做其他的事直到IO操作完

成了再回来进行。

消息模型:当遇到IO操作时,代码只负责发出IO请求,不等待IO结果,然后直接结束本轮消息处理,进入下一轮

消息处理过程。当IO操作完成后,将收到一条“IO完成”的消息,处理该消息时就可以直接获取IO操作结果。

子程序调用总是一个入口,一次返回,调用顺序是明确的,而协程的调用和子程序不同(有多个入口,多次返回)。

#协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行

协程子程序切换不是线程切换(系统自动执行),而是有程序自身控制。

#Python对协程的支持是通过generator实现的。

#在generator中,我们不但可以通过for循环来迭代,还可以不断调用next()函数获取有yield语句返回的下一个值。

#但是Python的yield不但可以返回一个值,还可以接收调用者发出的参数。

def consumer():

r=''

while True:

n=yield r

if not n:

return

print('[CONSUMER]Consuming %s...' % n)

r='200 OK'

def produce(c):

c.send(None)  #调用c.send(None)启动生成器,程序跳转到consumer,运行至yield 处结束返回produce.

n=0

while n<5:

n=n+1

print('[PRODUCER]Producing %s...' %n)

r=c.send(n) #通过c.send(n)切换到consumer执行

print('[PRODUCER]cONSUMER RETURN: %s' %r)

c.close()

c=consumer()

produce(c)

'''

1.首先调用c.send(None)启动生成器

2.然后,一旦产生了东西,通过c.send(n)切换到consumer执行

3.consumer通过yield拿到消息,处理,又通过yield把结果传回

4.produce拿到consumer处理的结果,继续生产下一条消息

5.produce决定不生产了,通过c.close()关闭consumer,整个过程结束。

整个流程无锁,由一个线程执行,produce和consumer协作完成任务,所以称为“协程”而非线程的抢占式多任务。

send()和yield相互为  发送和接收 参数  r=c.send(n),将参数n 传递给c函数,由c函数中的yield 及其后的变

量 接收,c中的程序再次运行到yield时,yield将其后的变量作为返回值,也就是c.send(n)的值

'''

'''

[PRODUCER]Producing 1...

[CONSUMER]Consuming 1...

[PRODUCER]cONSUMER RETURN: 200 OK

[PRODUCER]Producing 2...

[CONSUMER]Consuming 2...

[PRODUCER]cONSUMER RETURN: 200 OK

[PRODUCER]Producing 3...

[CONSUMER]Consuming 3...

[PRODUCER]cONSUMER RETURN: 200 OK

[PRODUCER]Producing 4...

[CONSUMER]Consuming 4...

[PRODUCER]cONSUMER RETURN: 200 OK

[PRODUCER]Producing 5...

[CONSUMER]Consuming 5...

[PRODUCER]cONSUMER RETURN: 200 OK

'''

#asyncio是Python3.4版本引入的标准库,直接内置了对异步IO的支持

#asyncio的编程模型就是一个消息循环。我们从asyncio模块中直接获取一个Eventloop的引用,然后把需要执行的协程扔到Eventloop中执行,就实现了异步IO。

#用asyncio实现Hello world 代码如下:

'''

import threading

import asyncio

@asyncio.coroutine

def hello():

print('Hello world! (%s)' %threading.currentThread())

yield from asyncio.sleep(1)

print('Hello again!(%s)' % threading.currentThread())

loop=asyncio.get_event_loop()

tasks=[hello(),hello()]

loop.run_until_complete(asyncio.wait(tasks))

loop.close()

'''

'''

Hello world! (<_MainThread(MainThread, started 5524)>)

Hello world! (<_MainThread(MainThread, started 5524)>)

(暂停约1秒)

Hello again!(<_MainThread(MainThread, started 5524)>)

Hello again!(<_MainThread(MainThread, started 5524)>)

'''

# @asyncio.coroutine把一个generator标记为corroutine类型,然后,我们就把这个coroutine扔到Eventloop

中执行。

#hello()会首先打印出Hello world!,然后,yield from 语法可以让我们方便地调用另一个generator.由于

asyncio.sleep()也是一个coroutine,所以线程不会等待

#asyncio.sleep(),而是直接中断并执行下一个消息循环。当asyncio.sleep()返回时,线程就可以从yield from

拿到返回值(此处是None),然后接着执行下一行语句。

#把asyncio.sleep(1)看成是一个耗时1秒的IO操作,在此期间,主线程并未等待,而是去执行Eventloop中其他可以执

行的coroutine了,因此可以实现并发执行。

多个coroutine可以封装成一组task然后并发执行。

asyncio的编程模型就是一个消息循环。我们从asyncio模块中直接获取一个Eventloop的引用,然后把需要执行的协程扔

到Eventloop中执,就实现了异步IO。

为了简化并更好地标识异步IO,从Python3.5开始引入新的语法async和await,可以让coroutine的代码更简洁易读。

'''

1. 把@asyncio.coroutine替换为async;

2. 把yield from 替换为await

'''

#例

'''

@asyncio.coroutine

def hello():

print("hello world!")

r = yield from asyncio.sleep(1)

print("hello again!")

'''

#可写成

'''

async def hello():

print("hello world!")

r=await asyncio.sleep(1)

print("hello again!")

'''

#剩下的代码保持不变

#aiohttp

#asyncio可以实现单线程并发IO操作。如果仅用在客户端,发挥的威力不大。如果把asyncio用在服务器端,例如web服务器,由于http连接就是IO操作,因此可以用

#单线程+coroutine实现多用户的高并发支持。

#asyncio实现了TCP UDP SSL等协议,aiohttp则是基于asyncio实现的http框架。

#编写一个http服务器    ,分别处理一下URL:

'''

* /  -首页返回b'<h1>Index</h1>';

* /hello/{name}  -根据URL参数返回文本 hello,%s!.

'''

import asyncio

from aiohttp import web

async def index(request):

await asyncio.sleep(0.5)

return web.Response(body=b'<h1>Index</h1>',content_type='text/html')

async def hello(request):

await asyncio.sleep(0.5)

text='<h1>hello, %s!<h1>' %request.match_info['name']

return web.Response(body=text.encode('utf-8'),content_type='text/html')

async def init(loop):

app=web.Application(loop=loop)

app.router.add_route('GET','/',index)

app.router.add_route('GET','/hello/{name}',hello)

srv=await loop.create_server(app.make_handler(),'127.0.0.1',8000)

print('Server started at http://127.0.0.1:8000...')

return srv

loop=asyncio.get_event_loop()

loop.run_until_complete(init(loop))

loop.run_forever()

#aiohttp的初始化函数init()也是一个coroutine,loop.create_server()则利用asyncio创建TCP服务

转载于:https://www.cnblogs.com/Ting-light/p/9547350.html

异步IO(协程,消息循环队列)相关推荐

  1. python find()效率_基于python分别采用同步与异步(协程)方式抓取时光网TOP100电影...

    欢迎各位小哥哥小姐姐阅读本的文章,对大家学习有帮助,请点赞加关注哦!!!!!!!!!! 您的点赞和关注将是我持续更新的动力呢.^v^ 有不懂的问题可以私聊我哦! 如题,同步运行就是python按照代码 ...

  2. Python 异步,协程,学起来好头疼,Python爬虫程序能调用GPU去爬东西吗?

    78 技术人社群日报时间 文章目录 Python 爬虫程序能调用 GPU 去爬东西吗? Python 异步,协程--,学起来好头疼 有没有牛子大的说下 `matplotlib` 里 `plot` 和 ...

  3. python asyncio 异步编程-协程 2

    asyncio 异步编程 官方文档: 中文版:https://docs.python.org/zh-cn/3.8/library/asyncio.html 英文本:https://docs.pytho ...

  4. python 协程可以嵌套协程吗_Python实战异步爬虫(协程)+分布式爬虫(多进程)

    引言:我们在写爬虫时常会遇到这样的问题,当需要爬取多个URL时,写一个普通的基于requests库的爬虫程序爬取时间会很长.因为是顺序请求网页的,而网页请求和获得响应过程比较耗费时间,程序不得不等待获 ...

  5. python异步爬虫_Python实战异步爬虫(协程)+分布式爬虫(多进程)

    转自:https://blog.csdn.net/SL_World/article/details/86633611 在讲解之前,我们先来通过一幅图看清多进程和协程的爬虫之间的原理及其区别.(图片来源 ...

  6. python asyncio 异步编程---协程

    1.协程 官方描述; 协程是子例程的更一般形式. 子例程可以在某一点进入并在另一点退出. 协程则可以在许多不同的点上进入.退出和恢复. 它们可通过 async def 语句来实现. 参见 PEP 49 ...

  7. python并发编程之多进程、多线程、异步和协程

    转载 自 tyomcat: https://www.cnblogs.com/tyomcat/p/5486827.html 一.多线程 多线程就是允许一个进程内存在多个控制权,以便让多个函数同时处于激活 ...

  8. python异步爬虫协程的使用学习笔记

    最近学异步的时候对于协程的理解比较困难,感觉对于之前的多线程也有也陌生了(下个文章写一下多线程巩固一下) 目录 先来说明一下协程的定义: asynico库使用 一 . event_loop事件循环 二 ...

  9. unity协程计时器循环调用

    用协程 循坏刷新扫光特效 using DG.Tweening; using Coffee.UIEffects; private UIShiny[] effList => transform.Ge ...

最新文章

  1. pyhton object is not subscriptable 解决
  2. 判断N!中二进制中最低位1的位置
  3. Prefix Sum Primes
  4. 用于大型的科学计算的计算机,科学计算器广泛适用于大、中、小学生、教师、科研人员及其他各界...
  5. layui 如何去dom_javascript 怎么去引用layui里面的方法
  6. html自动滚屏效果,jQuery实现公告新闻自动滚屏效果实例代码
  7. java生成xml_在JAVA生成XML文件
  8. linux缓冲区攻击实验报告,linux 下缓冲区溢出攻击原理及示例
  9. 在ubuntu14.04中安装及测试OpenCV
  10. xxx is not mapped 错误 解决方案
  11. 41 岁蚂蚁金服总裁助理去世; 华为首款 5G 手机欧洲上市;库克首谈 5G iPhone | 极客头条...
  12. wow.js中各种特效对应的类名
  13. tif软件Android版下载,TIF文件查看器
  14. IDEA开发环境中maven 项目配置使用JDK9,JDK10,JDK11,JDK12等
  15. springboot+责任链模式初体验
  16. 利用BeautifulSoup爬取豆瓣高分电影排行榜
  17. 你好,罗茜——爱要怎么说出口
  18. Android App包瘦身优化
  19. 3_Intellij_Idea在Debug模式下如何在控制台输入
  20. R语言基础编程技巧汇编 - 20

热门文章

  1. Spring Boot 解决跨域问题的 3 种方案!
  2. 重磅!阿里推出国产开源的jdk!
  3. 问一下,线程池里面到底该设置多少个线程?
  4. 干货 | 阿里巴巴混沌测试工具ChaosBlade两万字解读
  5. 目标检测模型从训练到部署!
  6. GNN教程:Weisfeiler-Leman算法!
  7. 中科大倪茹:感谢开源,我从入门竞赛到Top 10的经验分享
  8. 「数据分析」之零基础入门数据挖掘
  9. 达观杯_构建模型(一)linearSVM
  10. 使用神经网络提取PDF表格工具来了,支持图片,关键是能白嫖谷歌GPU资源