# asyncio
- Python3.4开始引入标准库当中,内置对异步io的支持
- asyncio本身是一个消息循环
- 步骤:
- 1、创建消息循环
- 2、把协成加进去
- 3、关闭
# asyncio异步协成,简单案例1 import threading import asyncio @asyncio.coroutine # 使用协成 def hello(): print('Hello world! (%s)' % threading.currentThread()) print('Start...(%s)' % threading.currentThread()) yield from asyncio.sleep(5) print('Done...(%s)' % threading.currentThread()) print('Hello again! (%s)' % threading.currentThread()) # 启动消息循环 loop = asyncio.get_event_loop() # 定义任务 tasks = [hello(), hello()] # asyncio使用wait等待tasks执行完毕 loop.run_until_complete(asyncio.wait(tasks)) # 关闭消息寻混 loop.close() '''
输出打印如下: Hello world! (<_MainThread(MainThread, started 9272)>) Start...(<_MainThread(MainThread, started 9272)>) Hello world! (<_MainThread(MainThread, started 9272)>) Start...(<_MainThread(MainThread, started 9272)>) Done...(<_MainThread(MainThread, started 9272)>) Hello again! (<_MainThread(MainThread, started 9272)>) Done...(<_MainThread(MainThread, started 9272)>) Hello again! (<_MainThread(MainThread, started 9272)>) ''' # asyncio异步用协成请求网络地址,案例2 import asyncio @asyncio.coroutine def wget(host): print('weget %s...' % host) # 异步请求网络地址 connect = asyncio.open_connection(host, 80) reader, writer = yield from connect header = 'GET / HTTP/1.0 Host: %s ' % host writer.writer(header.encode('utf-8')) yield from writer.drain() while True: line = yield from reader.readline() # http协议的换行使用 if line ==b' ': break print('%s header > %s' % (host, line.decode('utf-8').rstrip())) writer.close() loop = asyncio.get_event_loop() tasks = [wget(host) for host in ['www.sina.com.cn', 'www.sohu.com']] loop.run_until_complete(asyncio.wait(tasks)) loop.close() '''
输出打印如下
weget www.sina.com.cn... weget www.sohu.com... '''
# asyncio and await
- 为了更好的表示异步io
- Python3.5引入
- 让协成代码更简洁
- 使用上,可以简单的进行替换
- 用asyncio替换@asyncio.coroutine
- 用await替换yield from
import asyncio #@asyncio.coroutine # 使用协成 async def hello(): print('Hello world! (%s)' % threading.currentThread()) print('Start...(%s)' % threading.currentThread()) #yield from asyncio.sleep(5) await asyncio.sleep(5) print('Done...(%s)' % threading.currentThread()) print('Hello again! (%s)' % threading.currentThread()) # 启动消息循环 loop = asyncio.get_event_loop() # 定义任务 tasks = [hello(), hello()] # asyncio使用wait等待tasks执行完毕 loop.run_until_complete(asyncio.wait(tasks)) # 关闭消息寻混 loop.close()
# aiohttp
- asyncio实现单线程的并发io,在客户端用处不大
- 在服务器端可以asyncio+coroutine配合,因为http是io操作
- asyncio实现了tcp,udp,ssl等协议
- aiohttp是给与asyncio实现的http框架
- pip install aiohttp安装
# aiohttp案例 import asyncio from aiohttp import web async def index(request): await asyncio.sleep(0.5) return web.Response(body=b'<h1>Index</h1>') 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')) 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', 8080) print('Server started at http://127.0.0.1:8080...') return srv loop = asyncio.get_event_loop() loop.run_until_complete(init(loop)) loop.run_forever()
# concurrent.futures
- Python3新增的库
- 类似其他语言的线程池概念
- 利用multiprocessing实现真正的计算
- 核心原理:以子进程的形式,并行运行多个python解释器
从而令Python程序可以利用多核CPU来提升执行速度
由于子进程与主解释器相分离,所以他们的全局解释器锁也是相互独立的
每个子进程都能够完整的使用一个CPU内核
- concurrent.futures.Executor
- ThreadPoolExecutor
- ProcessPoolExecutor
执行的时候上面二者之间自行选择
- submit(fn, args, kwargs)
- fn:异步执行的函数
- args, kwargs传参
# 关于concurrent.futures案例 from concurrent.futures import ThreadPoolExecutor import time def return_future(msg): time.sleep(3) return msg # 创建一个线程池 pool = ThreadPoolExecutor(max_workers=2) # 往线程池加入两个task f1 = pool.submit(return_future, 'hello') f2 = pool.submit(return_future, 'world') # done等待执行完毕 print(f1.done()) time.sleep(3) print(f2.done()) # result结果 print(f1.result()) print(f2.result()) '''
输出打印如下:
False True hello world '''
# concurrent中的map函数
- map(fn, *iterables, timeout=None)
- 第二个参数跟可迭代的对象
- 很map函数类似
- 函数需要异步执行
- timeout:超时时间
- map跟submit选一个使用就行
# map案例 import time, re import os, datetime from concurrent import futures data = ['1', '2'] def wait_on(argument): print(argument) time.sleep(2) return "ok" ex = futures.ThreadPoolExecutor(max_workers=2) for i in ex.map(wait_on, data): print(i) ''' 输出打印如下: 1 2 ok ok '''
# Future
- 小美的同学三分钟后要到小美家里做客,小美想送给同学一条烟作为礼物
- 可是小美手头没烟
- 于是让二狗帮忙去买烟,路程耗时20分钟
- 等同学到家后,小美只好想辙指着空礼物盒对同学说这是给你的礼物,等你走的时候带走,先放这
- 随后小美和同学吹了一小时牛逼
- 期间27分钟后二狗带着烟回来了,把烟放入了礼物盒
- 两小时候同学离开,并带走了小美送他的礼物
- 礼物盒就是Future