asyncio模块作用:构建协程并发应用的工具
python并发的三大内置模块,简单认识:
1、multiprocessing:多进程并发处理2、threading模块:多线程并发处理3、asyncio模块:协程并发处理
1、启动一个协程,任务无返回值,需要注意:async的使用
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncio#开头定义async,表示要在协程运行,不定义的话,循环监听增加不了
async defcoroutine():print('协程运行...')#定义一个事件循环监听
event_loop =asyncio.get_event_loop()try:print('协程开始...')
coroutine_obj=coroutine()print('进入事件循环监听...')
event_loop.run_until_complete(coroutine())#run_until_complete翻译成中文:一直运行到完成为止
finally:print('关闭事件循环监听..')
event_loop.close()
asyncio_coroutine.py
运行效果
[root@ mnt]# python3 asyncio_coroutine.py
协程开始...
进入事件循环监听...
协程运行...
关闭事件循环监听..
sys:1: RuntimeWarning: coroutine 'coroutine' was never awaited
2、启动一个协程,任务有返回值,需要注意:async的使用
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncio#开头定义async,表示要在协程运行,不定义的话,循环监听增加不了
async defcoroutine():print('协程运行...')return 'ok'
#定义一个事件循环监听
event_loop =asyncio.get_event_loop()try:
coroutine_obj=coroutine()
return_value= event_loop.run_until_complete(coroutine()) #run_until_complete翻译成中文:一直运行到完成为止
print('coroutine()返回值:', return_value)finally:
event_loop.close()
asyncio_coroutine_return.py
运行效果
[root@ mnt]# python3 asyncio_coroutine_return.py
协程运行...
coroutine()返回值: ok
sys:1: RuntimeWarning: coroutine 'coroutine' was never awaited
3、启动一个协程,任务调用其它任务运行,需要注意:await 的使用
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncio#开头定义async,表示要在协程运行,不定义的话,循环监听增加不了
async defcoroutine():print('coroutine内部运行')print('等待task_1运行结果')
task1= await task_1() #await作用:控制运行流程,按顺序执行,即等待该函数运行完成,再继续往后执行
print('等待task_2运行结果')
task2=await task_2(task1)return(task1, task2)
asyncdeftask_1():print('task_1内部运行')return 'task_1 ok'asyncdeftask_2(arg):print('task_2内部运行')return 'task_2 arg:{}'.format(arg)#定义一个事件循环监听
event_loop =asyncio.get_event_loop()try:
coroutine_obj=coroutine()
return_value= event_loop.run_until_complete(coroutine()) #run_until_complete翻译成中文:一直运行到完成为止
print('coroutine()返回值:', return_value)finally:
event_loop.close()
asyncio_coroutine_chain.py
运行效果
[root@ mnt]# python3 asyncio_coroutine_chain.py
coroutine内部运行
等待task_1运行结果
task_1内部运行
等待task_2运行结果
task_2内部运行
coroutine()返回值: ('task_1 ok', 'task_2 arg:task_1 ok')
sys:1: RuntimeWarning: coroutine 'coroutine' was never awaited
4、生成器而不是协程
Python3早期版本的语法如下
@asyncio.coroutine 替换为 async
yield from 替换为 await
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncio#开头定义async,表示要在协程运行,不定义的话,循环监听增加不了
@asyncio.coroutinedefcoroutine():print('coroutine内部运行')print('等待task_1运行结果')
task1= yield from task_1() #await作用:控制运行流程,按顺序执行,即等待该函数运行完成,再继续往后执行
print('等待task_2运行结果')
task2= yield fromtask_2(task1)return(task1, task2)
@asyncio.coroutine
asyncdeftask_1():print('task_1内部运行')return 'task_1 ok'@asyncio.coroutine
asyncdeftask_2(arg):print('task_2内部运行')return 'task_2 arg:{}'.format(arg)#定义一个事件循环监听
event_loop =asyncio.get_event_loop()try:
coroutine_obj=coroutine()
return_value= event_loop.run_until_complete(coroutine()) #run_until_complete翻译成中文:一直运行到完成为止
print('coroutine()返回值:', return_value)finally:
event_loop.close()
asyncio_generator.py
运行效果
[root@ mnt]# python3 asyncio_generator.py
coroutine内部运行
等待task_1运行结果
task_1内部运行
等待task_2运行结果
task_2内部运行
coroutine()返回值: ('task_1 ok', 'task_2 arg:task_1 ok')
5、协程回调函数调用,此示例:讯速回调
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncioimportfunctoolsdef callback(arg, *, kwarg='default'):print('回调函数arg={},kwarg={}'.format(arg, kwarg))
asyncdefmain(loop):print('注册回调函数')
loop.call_soon(callback,1) #执行回调函数,传入参数1
wrapped = functools.partial(callback, kwarg='not default') #利用偏函数,给kwarg传默认值
loop.call_soon(wrapped, 2) #执行回调函数,传入参数2
await asyncio.sleep(0.5)
event_loop=asyncio.get_event_loop()try:print('进入事件循环监听')
event_loop.run_until_complete(main(event_loop))#将事件循环对象传入main函数中
finally:print('关闭事件循环监听')
event_loop.close()
asyncio_call_soon.py
运行效果
[root@ mnt]# python3 asyncio_call_soon.py
进入事件循环监听
注册回调函数
回调函数arg=1,kwarg=default
回调函数arg=2,kwarg=not default
关闭事件循环监听
6、协程回调函数调用,此示例:延时回调
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasynciodefcallback(arg):print('回调函数arg={}'.format(arg))
asyncdefmain(loop):print('注册回调函数')
loop.call_later(1,callback,'延时1秒回调参数1')
loop.call_later(1,callback,'延时1秒回调参数2')
loop.call_soon(callback,'讯速的回调参数')
await asyncio.sleep(3)
event_loop=asyncio.get_event_loop()try:print('进入事件循环监听')
event_loop.run_until_complete(main(event_loop))#将事件循环对象传入main函数中
finally:print('关闭事件循环监听')
event_loop.close()
asyncio_call_delay.py
运行效果
[root@ mnt]# python3 asyncio_call_delay.py
进入事件循环监听
注册回调函数
回调函数arg=讯速的回调参数
回调函数arg=延时1秒回调参数1
回调函数arg=延时1秒回调参数2
关闭事件循环监听
7、协程回调函数调用,此示例:指定时间回调
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncioimporttimedefcallback(arg, loop):print('回调函数arg={} 回调的时间time={}'.format(arg, loop.time()))
asyncdefmain(loop):
now=loop.time()print('时钟时间:{}'.format(time.time()))print('时事件循环时间:{}'.format(loop.time()))print('注册回调函数')
loop.call_at(now+ 1, callback, '参数1', loop)
loop.call_at(now+ 2, callback, '参数2', loop)
loop.call_soon(callback,'讯速的回调参数', loop)
await asyncio.sleep(4)
event_loop=asyncio.get_event_loop()try:print('进入事件循环监听')
event_loop.run_until_complete(main(event_loop))#将事件循环对象传入main函数中
finally:print('关闭事件循环监听')
event_loop.close()
asyncio_call_at.py
运行结果
[root@ mnt]# python3 asyncio_call_at.py
进入事件循环监听
时钟时间:1576030580.730174时事件循环时间:233762.828430848注册回调函数
回调函数arg=讯速的回调参数 回调的时间time=233762.828485111回调函数arg=参数1 回调的时间time=233763.829784903回调函数arg=参数2 回调的时间time=233764.831077136关闭事件循环监听
8、基于Future实现异步返回任务执行结果
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasynciodefmark_done(future, result):"""标记完成的函数"""
print('设置 Future 返回结果 {}'.format(result))
future.set_result(result)
event_loop=asyncio.get_event_loop()try:
all_done=asyncio.Future()print('调度标记完成的函数')
event_loop.call_soon(mark_done, all_done,'这个是调度传入的数据')
result=event_loop.run_until_complete(all_done)print('运行返回的结果:{}'.format(result))finally:print('关闭事件循环监听')
event_loop.close()print('Future 返回的结果: {}'.format(all_done.result()))"""结论:
返回结果可以从两个地方获取:
1、result = event_loop.run_until_complete(all_done)
2、Future.result()"""
asyncio_future_event_loop.py
运行效果
[root@ mnt]# python3 asyncio_future_event_loop.py
调度标记完成的函数
设置 Future 返回结果 这个是调度传入的数据
运行返回的结果:这个是调度传入的数据
关闭事件循环监听
Future 返回的结果: 这个是调度传入的数据
9、基于Future+await类现异步返回任务执行结果
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasynciodefmark_done(future, result):"""标记完成的函数"""
print('设置 Future 返回结果 {}'.format(result))
future.set_result(result)
asyncdefmain(loop):
all_done=asyncio.Future()print('调度标记完成的函数')
loop.call_soon(mark_done, all_done,'这个是调度传入的数据')
result= await all_done #await作用:等all_done返回结果,再往下运行
print('mark_done()执行完成,返回值 : {}'.format(result))
event_loop=asyncio.get_event_loop()try:
event_loop.run_until_complete(main(event_loop))finally:print('关闭事件循环监听')
event_loop.close()
asyncio_future_await.py
运行效果
[root@ mnt]# python3 asyncio_future_await.py
调度标记完成的函数
设置 Future 返回结果 这个是调度传入的数据
mark_done()执行完成,返回值 : 这个是调度传入的数据
关闭事件循环监听
10、基于Future的回调
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncioimportfunctoolsdefcallback(future, n):print('{}: future 完成: {}'.format(n, future.result()))
asyncdefregister_callbacks(future_obj):print('将回调函数注册到Future中')#这里需要注意的是add_done_callback函数,还为把当前实例对象作为参数,传给函数,所以回调函数多一个callback(future, n)
future_obj.add_done_callback(functools.partial(callback, n=1))
future_obj.add_done_callback(functools.partial(callback, n=2))
asyncdefmain(future_obj):#注册future的回调函数
await register_callbacks(future_obj)print('设置Future返回结果')
future_obj.set_result('the result')
event_loop=asyncio.get_event_loop()try:#创建一个future实例
future_obj =asyncio.Future()#增future实例传给main函数处理
event_loop.run_until_complete(main(future_obj))finally:
event_loop.close()
asyncio_future_callback.py
运行效果
[root@ mnt]# python3 asyncio_future_callback.py
将回调函数注册到Future中
设置Future返回结果1: future 完成: the result2: future 完成: the result
11、asyncio创建任务运行
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncio
asyncdeftask_func():print('task_func 执行完成')return 'task_func返回值ok'asyncdefmain(loop):print('创建任务')
task=loop.create_task(task_func())print('等待task的结果 {}'.format(task))
return_value= await task #直到遇到await,上面的task开始运行
print('已完成任务{}'.format(task)) #经过上面的运行,task里面已经有result执行结果
print('return value: {}'.format(return_value))
event_loop=asyncio.get_event_loop()try:
event_loop.run_until_complete(main(event_loop))finally:
event_loop.close()
asyncio_future_create_task.py
运行结果
[root@ mnt]# python3 asyncio_future_create_task.py
创建任务
等待task的结果>task_func 执行完成
已完成任务 result='task_func返回值ok'>return value: task_func返回值ok
12、asyncio取消任务运行
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncio
asyncdeftask_func():print('task_func 执行完成')return 'task_func返回值ok'asyncdefmain(loop):print('创建任务')
task=loop.create_task(task_func())print('取消任务')
task.cancel()print('取消任务结果 {}'.format(task))try:
await task#直到遇到await,上面的task开始运行
exceptasyncio.CancelledError:print('从已取消的任务中捕获错误')else:print('任务执行结果 {}'.format(task))
event_loop=asyncio.get_event_loop()try:
event_loop.run_until_complete(main(event_loop))finally:
event_loop.close()
asyncio_future_create_cancel_task.py
运行效果
[root@python-mysql mnt]# python3 asyncio_future_create_cancel_task.py
创建任务
取消任务
取消任务结果>从已取消的任务中捕获错误
13、利用回调取消任务执行
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncio
asyncdeftask_func():print('task_func睡眠')try:
await asyncio.sleep(1)exceptasyncio.CancelledError:print('task_func 任务取消')raise
return 'task_func返回值ok'
deftask_canceller(task_obj):print('task_canceller运行')
task_obj.cancel()print('取消task_obj任务')
asyncdefmain(loop):print('创建任务')
task=loop.create_task(task_func())
loop.call_soon(task_canceller, task)try:
await task#直到遇到await,上面的task开始运行
exceptasyncio.CancelledError:print('从已取消的任务中捕获错误')else:print('任务执行结果 {}'.format(task))
event_loop=asyncio.get_event_loop()try:
event_loop.run_until_complete(main(event_loop))finally:
event_loop.close()
asyncio_future_create_callback_cancel_task.py
运行效果
[root@ mnt]# python3 asyncio_future_create_callback_cancel_task.py
创建任务
task_func睡眠
task_canceller运行
取消task_obj任务
task_func 任务取消
从已取消的任务中捕获错误
14、asyncio.ensure_future(),增加函数,直到await才运行
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncio
asyncdefwrapped():print('wrapped 运行')return 'wrapped result'asyncdefinner(task):print('inner: 开始运行')print('inner: task {!r}'.format(task))
result=await taskprint('inner: task 返回值 {!r}'.format(result))
asyncdefstart_task():print('开始创建task')
task=asyncio.ensure_future(wrapped())print('等待inner运行')
await inner(task)print('starter: inner returned')
event_loop=asyncio.get_event_loop()try:print('进程事件循环')
result=event_loop.run_until_complete(start_task())finally:
event_loop.close()
asyncio_ensure_future.py
运行效果
[root@ mnt]# python3 asyncio_ensure_future.py
进程事件循环
开始创建task
等待inner运行
inner: 开始运行
inner: task>wrapped 运行
inner: task 返回值'wrapped result'
15、asyncio.wait()批量等待多个协程直到运行完成,包装多个返回显示结果
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncio
asyncdefphase(i):print('phase形参传入值{}'.format(i))
await asyncio.sleep(0.1 *i)print('完成phase的次数{}'.format(i))return 'phase {} result'.format(i)
asyncdefmain(num_phase):print('main函数开始')
phases=[
phase(i)for i inrange(num_phase)
]print('等待phases里面的多个函数执行完成')
completed, pending= await asyncio.wait(phases) #completed : 运行完成存在这里 ,pending : 没有运行完成存在这里
for_completed_results = [t.result() for t incompleted]print('for_completed_results : {}'.format(for_completed_results))
event_loop=asyncio.get_event_loop()try:print('进程事件循环')
result= event_loop.run_until_complete(main(3))finally:
event_loop.close()
asyncio_wait.py
运行效果
[root@ mnt]# python3 asyncio_wait.py
进程事件循环
main函数开始
等待phases里面的多个函数执行完成
phase形参传入值2
phase形参传入值0
phase形参传入值1
完成phase的次数0
完成phase的次数1
完成phase的次数2
for_completed_results : ['phase 2 result', 'phase 0 result', 'phase 1 result']
16、asyncio.wait()批量等待多个协程设置超时时间并且取消未完成的任务,包装多个返回显示结果
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncio
asyncdefphase(i):print('phase形参传入值{}'.format(i))try:
await asyncio.sleep(0.1 *i)exceptasyncio.CancelledError:print('phase {} 取消'.format(i))else:print('完成phase的次数{}'.format(i))return 'phase {} result'.format(i)
asyncdefmain(num_phase):print('main函数开始')
phases=[
phase(i)for i inrange(num_phase)
]print('等待phases里面的多个函数执行完成')
completed, pending= await asyncio.wait(phases, timeout=0.1) #completed : 运行完成存在这里 ,pending : 没有运行完成存在这里
print('completed长度:{},pending长度 :{}'.format(len(completed), len(pending)))ifpending:print('取消未完成的任务')for t inpending:
t.cancel()print('main函数执行完成')
event_loop=asyncio.get_event_loop()try:print('进程事件循环')
result= event_loop.run_until_complete(main(3))finally:
event_loop.close()
asyncio_wait_timeout.py
运行效果
[root@ mnt]# python3 asyncio_wait_timeout.py
进程事件循环
main函数开始
等待phases里面的多个函数执行完成
phase形参传入值1
phase形参传入值2
phase形参传入值0
完成phase的次数0
completed长度:1,pending长度 :2取消未完成的任务
main函数执行完成
phase1取消
phase2 取消
17、asyncio.gather()多个协程运行,函数返回值接收
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncio
asyncdefphase1():print('phase1运行中')
await asyncio.sleep(2)print('phase1运行完成')return 'phase1 result'asyncdefphase2():print('phase2运行中')
await asyncio.sleep(1)print('phase2运行完成')return 'phase2 result'asyncdefmain():print('main函数开始')
results=await asyncio.gather(
phase1(),
phase2()
)print('results : {}'.format(results))
event_loop=asyncio.get_event_loop()try:print('进程事件循环')
result=event_loop.run_until_complete(main())finally:
event_loop.close()
asyncio_gather.py
运行效果
[root@ mnt]# python3 asyncio_gather.py
进程事件循环
main函数开始
phase1运行中
phase2运行中
phase2运行完成
phase1运行完成
results : ['phase1 result', 'phase2 result']
18、asyncio.as_completed()多个协程运行,函数返回值不是有序的接收
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncio
asyncdefphase(i):print('phase {} 运行中'.format(i))
await asyncio.sleep(0.5 - (0.1 *i))print('phase {} 运行完成'.format(i))return 'phase {} result'.format(i)
asyncdefmain(num_phases):print('main函数开始')
phases=[
phase(i)for i inrange(num_phases)
]print('等待phases运行完成')
results=[]for next_to_complete inasyncio.as_completed(phases):
task_result=await next_to_completeprint('接到到task_result : {}'.format(task_result))
results.append(task_result)print('results : {}'.format(results))returnresults
event_loop=asyncio.get_event_loop()try:print('进程事件循环')
event_loop.run_until_complete(main(3))finally:
event_loop.close()
asyncio_as_completed.py
运行效果
[root@ mnt]# python3 asyncio_as_completed.py
进程事件循环
main函数开始
等待phases运行完成
phase2运行中
phase1运行中
phase0运行中
phase2运行完成
接到到task_result : phase2result
phase1运行完成
接到到task_result : phase1result
phase0运行完成
接到到task_result : phase0result
results : ['phase 2 result', 'phase 1 result', 'phase 0 result']
19、asyncio.Lock() 协程锁的打开与关闭
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncioimportfunctoolsdefunlock(lock):print('回调释放锁')
lock.release()
asyncdefcoro1(lock):"""with方式获得锁"""async with lock:print('coro1 打开锁运算')print('coro1 锁已释放')
asyncdefcoro2(lock):"""传统方式获取锁"""await lock.acquire()try:print('coro2 打开锁运算')finally:print('coro2 锁已释放')
lock.release()
asyncdefmain(loop):
lock=asyncio.Lock()print('启动协程之前获取锁')
await lock.acquire()print('获得锁 {}'.format(lock.locked()))#运行完成,回调解锁
loop.call_later(0.1, functools.partial(unlock, lock))print('等待协程运行')
await asyncio.wait([coro1(lock), coro2(lock)])
event_loop=asyncio.get_event_loop()try:
event_loop.run_until_complete(main(event_loop))finally:
event_loop.close()
asyncio_lock.py
运行效果
[root@ mnt]# python3 asyncio_lock.py
启动协程之前获取锁
获得锁 True
等待协程运行
回调释放锁
coro2 打开锁运算
coro2 锁已释放
coro1 打开锁运算
coro1 锁已释放
20、asyncio.Event() 事件的查看与设置
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncioimportfunctoolsdefset_event(event):print('回调设置event')
event.set()
asyncdefcoro1(event):print('coro1 等待事件')
await event.wait()print('coro1 触发运行')
asyncdefcoro2(event):print('coro2 等待事件')
await event.wait()print('coro2 触发运行')
asyncdefmain(loop):
event=asyncio.Event()print('event开始之前状态:{}'.format(event.is_set()))
loop.call_later(0.1, functools.partial(set_event, event)) #延时0.1秒后,回调set_event函数
await asyncio.wait([coro1(event), coro2(event)])print('event开始之后状态:{}'.format(event.is_set()))
event_loop=asyncio.get_event_loop()try:
event_loop.run_until_complete(main(event_loop))finally:
event_loop.close()
asyncio_event
运行效果
[root@ mnt]# python3 asyncio_event.py
event开始之前状态:False
coro1 等待事件
coro2 等待事件
回调设置event
coro1 触发运行
coro2 触发运行
event开始之后状态:True
21、asyncio.Condition(),对事件状态单独通知执行
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncio
asyncdefconsumer(condition_obj, i):
async with condition_obj:print('消费者 {} 等待中'.format(i))
await condition_obj.wait()print('消费者 {} 触发'.format(i))print('消费者 {} 消费结束'.format(i))
asyncdefmanipulate_condition(condition_obj):print('开始操作condition')
await asyncio.sleep(0.1)for i in range(3):
async with condition_obj:print('通知消费者 {}'.format(i))
condition_obj.notify(i)
await asyncio.sleep(0.1)
async with condition_obj:print('通知其它所有的消费者')
condition_obj.notify_all()print('操作condition结束')
asyncdefmain(loop):#创建一个操作状态的对象
condition_obj =asyncio.Condition()#运5个消费者函数
consumers =[
consumer(condition_obj, i)for i in range(5)
]#创建一个操作状态的任务
loop.create_task(manipulate_condition(condition_obj))#等待consumers所有的函数执行完成
await asyncio.wait(consumers)
event_loop=asyncio.get_event_loop()try:
event_loop.run_until_complete(main(event_loop))finally:
event_loop.close()
asyncio_condition.py
运行效果
[root@ mnt]# python3 asyncio_condition.py
开始操作condition
消费者2等待中
消费者3等待中
消费者0等待中
消费者4等待中
消费者1等待中
通知消费者0通知消费者1消费者2触发
消费者2消费结束
通知消费者2消费者3触发
消费者3消费结束
消费者0触发
消费者0消费结束
通知其它所有的消费者
操作condition结束
消费者4触发
消费者4消费结束
消费者1触发
消费者1 消费结束
22、协程队列Queue,生产者与消费者的示例
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncio
asyncdefconsumer(n, q):print('消费者 {} 开始'.format(n))whileTrue:print('消费费 {} 等待消费'.format(n))
item=await q.get()print('消费者 {} 消费了 {}'.format(n, item))if item isNone:
q.task_done()break
else:
await asyncio.sleep(0.01 *item)
q.task_done()print('消费者 {} 结束'.format(n))
asyncdefproducer(q, num_worker):print('生产者 开始')for i in range(num_worker * 3):
await q.put(i)print('生产者 增加数据 {} 到队列中'.format(i))print('生产者 增加停止信号到队列中')for i inrange(num_worker):
await q.put(None)print('生产者 等待队列清空')
await q.join()print('生产者 结束')
asyncdefmain(loop, num_consumers):#创建一个队列,最大的长度是num_consumers
q = asyncio.Queue(maxsize=num_consumers)
consumers=[
loop.create_task(consumer(i, q))for i inrange(num_consumers)
]
producer_task=loop.create_task(producer(q, num_consumers))
await asyncio.wait(consumers+[producer_task])
event_loop=asyncio.get_event_loop()try:
event_loop.run_until_complete(main(event_loop,2))finally:
event_loop.close()
asyncio_queue.py
运行效果
[root@ mnt]# python3 asyncio_queue.py
消费者0开始
消费费0等待消费
消费者1开始
消费费1等待消费
生产者 开始
生产者 增加数据0到队列中
生产者 增加数据1到队列中
消费者0 消费了 0消费者1 消费了 1生产者 增加数据2到队列中
生产者 增加数据3到队列中
消费费0等待消费
消费者0 消费了 2生产者 增加数据4到队列中
消费费1等待消费
消费者1 消费了 3生产者 增加数据5到队列中
生产者 增加停止信号到队列中
消费费0等待消费
消费者0 消费了 4消费费1等待消费
消费者1 消费了 5生产者 等待队列清空
消费费0等待消费
消费者0消费了 None
消费者0结束
消费费1等待消费
消费者1消费了 None
消费者1结束
生产者 结束
23、利用 asyncio.Protocol 实现服务端和客户端数据相互传送
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncioimportloggingimportsys
SERVER_ADDRESS= ['localhost', 8000]classEchoServer(asyncio.Protocol):defconnection_made(self, transport):
self.transport=transport
self.address= transport.get_extra_info('peername')
self.log=logging.getLogger('EchoServer_{}_{}'.format(*self.address)
)
self.log.debug('接收连接')defdata_received(self, data):
self.log.debug('接收数据 {}'.format(data))
self.transport.write(data)
self.log.debug('发送数据 {}'.format(data))defeof_received(self):
self.log.debug('接收数据 EOF')ifself.transport.can_write_eof():
self.transport.write_eof()defconnection_lost(self, exc):ifexc:
self.log.error('错误 {}'.format(exc))else:
self.log.debug('服务关闭')
super(EchoServer, self).connection_lost(exc)
logging.basicConfig(
level=logging.DEBUG,
format='%(name)s : %(message)s',
stream=sys.stderr
)
log= logging.getLogger('main')
event_loop=asyncio.get_event_loop()
factory= event_loop.create_server(EchoServer, *SERVER_ADDRESS)
server=event_loop.run_until_complete(factory)
log.debug('开始运行 IP:{} Port:{}'.format(*SERVER_ADDRESS))try:
event_loop.run_forever()finally:
log.debug('关闭服务')
server.close()
event_loop.run_until_complete(server.wait_closed())
log.debug('关闭事件循环')
event_loop.close()
asyncio_echo_server_protocol.py
#!/usr/bin/env python3#encoding: utf-8
importasyncioimportfunctoolsimportloggingimportsys
MESSAGES=[
b'This is the message.',
b'It will be sent',
b'in parts.',
]
SERVER_ADDRESS= ('localhost', 8000)classEchoClient(asyncio.Protocol):def __init__(self, messages, future):
super().__init__()
self.messages=messages
self.log= logging.getLogger('EchoClient')
self.f=futuredefconnection_made(self, transport):
self.transport=transport
self.address= transport.get_extra_info('peername')
self.log.debug('连接服务器IP:{} port :{}'.format(*self.address)
)for msg inself.messages:
transport.write(msg)
self.log.debug('发送数据 {!r}'.format(msg))iftransport.can_write_eof():
transport.write_eof()defdata_received(self, data):
self.log.debug('received {!r}'.format(data))defeof_received(self):
self.log.debug('接收到 EOF')
self.transport.close()if notself.f.done():
self.f.set_result(True)defconnection_lost(self, exc):
self.log.debug('服务器关闭连接')
self.transport.close()if notself.f.done():
self.f.set_result(True)
super().connection_lost(exc)#设置日志级别
logging.basicConfig(
level=logging.DEBUG,
format='%(name)s: %(message)s',
stream=sys.stderr,
)#打印日志标题
log = logging.getLogger('main')#创建一个事件循环
event_loop =asyncio.get_event_loop()#创建客户端的Future
client_completed =asyncio.Future()#利用偏函数自动传参给EchoClient实例化类
client_factory =functools.partial(
EchoClient,
messages=MESSAGES,
future=client_completed,
)#创建一个事件循环连接
factory_coroutine =event_loop.create_connection(
client_factory,*SERVER_ADDRESS,
)
log.debug('等待客户端运行完成')try:
event_loop.run_until_complete(factory_coroutine)
event_loop.run_until_complete(client_completed)finally:
log.debug('关闭事件循环')
event_loop.close()
asyncio_echo_client_protocol.py
运行效果
服务端
[root@ mnt]# python3 asyncio_echo_server_protocol.py
asyncio : Using selector: EpollSelector
main : 开始运行 IP:localhost Port:8000EchoServer_::1_54082 : 接收连接
EchoServer_::1_54082 : 接收数据 b'This is the message. It will be sent in parts.'EchoServer_::1_54082 : 发送数据 b'This is the message. It will be sent in parts.'EchoServer_::1_54082 : 接收数据 EOF
EchoServer_::1_54082 : 服务关闭
客户端
[root@ mnt]# python3 asyncio_echo_client_protocol.py
asyncio: Using selector: EpollSelector
main: 等待客户端运行完成
EchoClient: 连接服务器IP:::1 port :8000EchoClient: 发送数据 b'This is the message.'EchoClient: 发送数据 b'It will be sent'EchoClient: 发送数据 b'in parts.'EchoClient: received b'This is the message. It will be sent in parts.'EchoClient: 接收到 EOF
EchoClient: 服务器关闭连接
main: 关闭事件循环
24、基于Coroutine 实现服务端和客户端数据相互传送,与22点示例功能一样)
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncioimportloggingimportsys
SERVER_ADDRESS= ('localhost', 8000)
asyncdefecho(reader, writer):
address= writer.get_extra_info('peername')
log= logging.getLogger('echo_{}_{}'.format(*address))
log.debug('开始接受连接')whileTrue:
data= await reader.read(128)ifdata:
log.debug('接受的数据 : {}'.format(data))
writer.write(data)
await writer.drain()
log.debug('发送数据:{}'.format(data))else:
log.debug('关闭连接')
writer.close()returnlogging.basicConfig(
level=logging.DEBUG,
format='%(name)s : %(message)s',
stream=sys.stderr
)
log= logging.getLogger('main')
event_loop=asyncio.get_event_loop()
factory= asyncio.start_server(echo, *SERVER_ADDRESS)
server=event_loop.run_until_complete(factory)
log.debug('开始启动服务 IP:{},Port:{}'.format(*SERVER_ADDRESS))try:
event_loop.run_forever()exceptKeyboardInterrupt:pass
finally:
log.debug('关闭服务端')
server.close()
event_loop.run_until_complete(server.wait_closed())
log.debug('关闭事件循环')
event_loop.close()
asyncio_echo_server_coroutine.py
#!/usr/bin/env python3#encoding: utf-8
importasyncioimportloggingimportsys
MESSAGES=[
b'This is the message.',
b'It will be sent',
b'in parts.',
]
SERVER_ADDRESS= ('localhost', 8000)
asyncdefecho_client(address, messages):
log= logging.getLogger('echo_client')
log.debug('连接服务器 to {} port {}'.format(*address))#创建与服务端连接
reader, writer = await asyncio.open_connection(*address)for msg inmessages:
writer.write(msg)
log.debug('发送数据: {}'.format(msg))#判断是否发送结束标记
ifwriter.can_write_eof():
writer.write_eof()#等待所有发送完成
await writer.drain()
log.debug('等待服务器响应')whileTrue:
data= await reader.read(128)ifdata:
log.debug('接收服务器数据 :{}'.format(data))else:
log.debug('关闭与服务器的连接')
writer.close()returnlogging.basicConfig(
level=logging.DEBUG,
format='%(name)s: %(message)s',
stream=sys.stderr,
)
log= logging.getLogger('main')
event_loop=asyncio.get_event_loop()try:
event_loop.run_until_complete(
echo_client(SERVER_ADDRESS, MESSAGES)
)finally:
log.debug('closing event loop')
event_loop.close()
asyncio_echo_client_coroutine.py
运行效果
服务端
[root@ mnt]# python3 asyncio_echo_server_coroutine.py
asyncio : Using selector: EpollSelector
main : 开始启动服务 IP:localhost,Port:8000echo_::1_54084 : 开始接受连接
echo_::1_54084 : 接受的数据 : b'This is the message. It will be sent in parts.'echo_::1_54084 : 发送数据:b'This is the message. It will be sent in parts.'echo_::1_54084 : 关闭连接
#这里使用Ctrl+C,运行后面的功能^Cmain : 关闭服务端
main : 关闭事件循环
客户端
[root@ mnt]# python3 asyncio_echo_client_coroutine.py
asyncio: Using selector: EpollSelector
echo_client: 连接服务器 to localhost port8000echo_client: 发送数据: b'This is the message.'echo_client: 发送数据: b'It will be sent'echo_client: 发送数据: b'in parts.'echo_client: 等待服务器响应
echo_client: 接收服务器数据 :b'This is the message. It will be sent in parts.'echo_client: 关闭与服务器的连接
main: closing event loop
25、基于Coroutine ,实现SSL的Socket通讯
#创建ssl证书
openssl req -newkey rsa:2048 -nodes -keyout test_ssl.key -x509 -days 800 -out test_ssl.crt
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncioimportloggingimportsysimportssl
SERVER_ADDRESS= ('localhost', 8000)
asyncdefecho(reader, writer):
address= writer.get_extra_info('peername')
log= logging.getLogger('echo_{}_{}'.format(*address))
log.debug('开始接受连接')whileTrue:
data= await reader.read(128)#因为ssl不支持EOF结束,所以需要用'\x00'结束
terminate = data.endswith(b'\x00')
data= data.rstrip(b'\x00')ifdata:
log.debug('接受的数据 : {}'.format(data))
writer.write(data)
await writer.drain()
log.debug('发送数据:{}'.format(data))if not data orterminate:
log.debug('关闭连接')
writer.close()returnlogging.basicConfig(
level=logging.DEBUG,
format='%(name)s : %(message)s',
stream=sys.stderr
)
log= logging.getLogger('main')
event_loop=asyncio.get_event_loop()#创建SSL所需要的对象
ssl_context =ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_context.check_hostname=False
ssl_context.load_cert_chain('test_ssl.crt', 'test_ssl.key')
factory= asyncio.start_server(echo, *SERVER_ADDRESS, ssl=ssl_context)
server=event_loop.run_until_complete(factory)
log.debug('开始启动服务 IP:{},Port:{}'.format(*SERVER_ADDRESS))try:
event_loop.run_forever()exceptKeyboardInterrupt:pass
finally:
log.debug('关闭服务端')
server.close()
event_loop.run_until_complete(server.wait_closed())
log.debug('关闭事件循环')
event_loop.close()
asyncio_echo_server_ssl.py
#!/usr/bin/env python3#encoding: utf-8
importasyncioimportloggingimportsysimportssl
MESSAGES=[
b'This is the message.',
b'It will be sent',
b'in parts.',
]
SERVER_ADDRESS= ('localhost', 8000)
asyncdefecho_client(address, messages):
log= logging.getLogger('echo_client')#客户端ssl所需要带证书访问
ssl_context =ssl.create_default_context(
ssl.Purpose.SERVER_AUTH
)
ssl_context.check_hostname=False
ssl_context.load_verify_locations('test_ssl.crt')
log.debug('连接服务器 to {} port {}'.format(*address))#创建与服务端连接
reader, writer = await asyncio.open_connection(*address, ssl=ssl_context)for msg inmessages:
writer.write(msg)
log.debug('发送数据: {}'.format(msg))#判断是否发送结束标记
#非ssl
#if writer.can_write_eof():
#writer.write_eof()
#ssl
writer.write(b'\x00')#等待所有发送完成
await writer.drain()
log.debug('等待服务器响应')whileTrue:
data= await reader.read(128)ifdata:
log.debug('接收服务器数据 :{}'.format(data))else:
log.debug('关闭与服务器的连接')
writer.close()returnlogging.basicConfig(
level=logging.DEBUG,
format='%(name)s: %(message)s',
stream=sys.stderr,
)
log= logging.getLogger('main')
event_loop=asyncio.get_event_loop()try:
event_loop.run_until_complete(
echo_client(SERVER_ADDRESS, MESSAGES)
)finally:
log.debug('closing event loop')
event_loop.close()
asyncio_echo_client_ssl.py
运行效果
服务端
[root@ mnt]# python3 asyncio_echo_server_ssl.py
asyncio : Using selector: EpollSelector
main : 开始启动服务 IP:localhost,Port:8000echo_::1_54094 : 开始接受连接
echo_::1_54094 : 接受的数据 : b'This is the message. It will be sent in parts.'echo_::1_54094 : 发送数据:b'This is the message. It will be sent in parts.'echo_::1_54094 : 关闭连接^Cmain : 关闭服务端
main : 关闭事件循环
客户端
[root@ mnt]# python3 asyncio_echo_client_ssl.py
asyncio: Using selector: EpollSelector
echo_client: 连接服务器 to localhost port8000echo_client: 发送数据: b'This is the message.'echo_client: 发送数据: b'It will be sent'echo_client: 发送数据: b'in parts.'echo_client: 等待服务器响应
echo_client: 接收服务器数据 :b'This is the message. It will be sent in parts.'echo_client: 关闭与服务器的连接
main: closing event loop
26、利用asyncio.SubprocessProtocol类继承的方式实现子进程的调用
#!/usr/bin/env python3#encoding: utf-8
#end_pymotw_header
importasyncioimportfunctoolsclassDFProtocol(asyncio.SubprocessProtocol):
FD_NAMES= ['stdin', 'stdout', 'stderr']def __init__(self, done_future):
self.done=done_future
self.buffer=bytearray()
super().__init__()defconnection_made(self, transport):print('process started {}'.format(transport.get_pid()))
self.transport=transportdefpipe_data_received(self, fd, data):print('read {} bytes from {}'.format(len(data),
self.FD_NAMES[fd]))if fd == 1:
self.buffer.extend(data)defprocess_exited(self):print('process exited')
return_code=self.transport.get_returncode()print('return code {}'.format(return_code))if notreturn_code:
cmd_output=bytes(self.buffer).decode()
results=self._parse_results(cmd_output)else:
results=[]
self.done.set_result((return_code, results))def_parse_results(self, output):print('parsing results')if notoutput:return[]
lines=output.splitlines()
headers=lines[0].split()
devices= lines[1:]
results=[
dict(zip(headers, line.split()))for line indevices
]returnresults
asyncdefrun_df(loop):print('in run_df')
cmd_done= asyncio.Future(loop=loop)
factory=functools.partial(DFProtocol, cmd_done)
proc=loop.subprocess_exec(
factory,'df', '-hl',
stdin=None,
stderr=None,
)try:print('launching process')
transport, protocol=await procprint('waiting for process to complete')
await cmd_donefinally:
transport.close()returncmd_done.result()
event_loop=asyncio.get_event_loop()try:
return_code, results=event_loop.run_until_complete(
run_df(event_loop)
)finally:
event_loop.close()ifreturn_code:print('error exit {}'.format(return_code))else:print('\nFree space:')for r inresults:print('{Mounted:25}: {Avail}'.format(**r))
asyncio_subprocess_protocol.py
运行效果
由于我使用的Python版本是3.6.6,调用的优先级是1、调用 def connection_made(self, transport) 函数2、调用 def process_exited(self)函数3、调用 def pipe_data_received(self, fd, data)函数这里是输出结果,所以结束进程的时候process_exited解析是空,导致结果出不来,这里待pyhton版本验证
27、利用协程子进程的调用
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasynciodef_parse_results(output):print('解析结果')if notoutput:return[]
lines=output.splitlines()
headers=lines[0].split()
devices= lines[1:]
results=[
dict(zip(headers, line.split()))for line indevices
]returnresults
asyncdefrun_df():print('run_df函数运行')
buffer=bytearray()
create=asyncio.create_subprocess_exec('df', '-h',
stdout=asyncio.subprocess.PIPE
)print('df -h开始运行')
proc=await createprint('进程开始 {}'.format(proc.pid))whileTrue:
line=await proc.stdout.readline()print('读取 : {}'.format(line))if notline:print('命令不再输出')breakbuffer.extend(line)print('等待进程运行完成')
await proc.wait()
return_code=proc.returncodeprint('运行返回码:{}'.format(return_code))if notreturn_code:
cmd_output=bytes(buffer).decode()
results=_parse_results(cmd_output)else:
results=[]return(return_code, results)
event_loop=asyncio.get_event_loop()try:
return_code, results=event_loop.run_until_complete(
run_df()
)finally:
event_loop.close()ifreturn_code:print('错误退出,错误信息:{}'.format(return_code))else:print('运行结果:')for r inresults:print('{Mounted:25}:{Avail}'.format(**r))
asyncio_subprocess_coroutine.py
运行效果
[root@ mnt]# python3 asyncio_subprocess_coroutine.py
run_df函数运行df -h开始运行
进程开始44244读取 : b'Filesystem Size Used Avail Use% Mounted on\n'读取 : b'/dev/mapper/centos-root 17G 7.9G 9.2G 47% /\n'读取 : b'devtmpfs 478M 0 478M 0% /dev\n'读取 : b'tmpfs 489M 0 489M 0% /dev/shm\n'读取 : b'tmpfs 489M 56M 433M 12% /run\n'读取 : b'tmpfs 489M 0 489M 0% /sys/fs/cgroup\n'读取 : b'/dev/sda1 1014M 125M 890M 13% /boot\n'读取 : b'tmpfs 98M 0 98M 0% /run/user/0\n'读取 : b''命令不再输出
等待进程运行完成
运行返回码:0解析结果
运行结果:/ :9.2G/dev :478M/dev/shm :489M/run :433M/sys/fs/cgroup :489M/boot :890M/run/user/0 :98M
28、利用协程管道传数据给子进程的调用处理
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncio
asyncdefto_upper(input):print('进程转大写的to_upper函数')
create=asyncio.create_subprocess_exec('tr', '[:lower:]', '[:upper:]',
stdout=asyncio.subprocess.PIPE,
stdin=asyncio.subprocess.PIPE,
)print('等待子进程运行完成')
proc=await createprint('子进程PID {}'.format(proc.pid))print('查看子进程运行的标准输出和错误')
stdout, stderr=await proc.communicate(input.encode())print('等待子进程完成')
await proc.wait()
return_code=proc.returncodeprint('return code {}'.format(return_code))if notreturn_code:
results=bytes(stdout).decode()else:
results= ''
return(return_code, results)
MESSAGE= """This message will be converted
to all caps."""event_loop=asyncio.get_event_loop()try:
return_code, results=event_loop.run_until_complete(
to_upper(MESSAGE)
)finally:
event_loop.close()ifreturn_code:print('错误时,退出的返回状态码 {}'.format(return_code))else:print('源数据: {!r}'.format(MESSAGE))print('处理过的数据 : {!r}'.format(results))
asyncio_subprocess_coroutine_write.py
运行效果
[root@ mnt]# python3 asyncio_subprocess_coroutine_write.py
进程转大写的to_upper函数
等待子进程运行完成
子进程PID78254查看子进程运行的标准输出和错误
等待子进程完成
return code0源数据:'\nThis message will be converted\nto all caps.\n'处理过的数据 :'\nTHIS MESSAGE WILL BE CONVERTED\nTO ALL CAPS.\n'
29、协程之信号的注册处理
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncioimportfunctoolsimportosimportsignaldefsignal_handler(name):print('正在处理信号 : {}'.format(name))
event_loop=asyncio.get_event_loop()#给信号绑定处理的事件
event_loop.add_signal_handler(
signal.SIGHUP,
functools.partial(signal_handler, name='SIGHUP'),
)
event_loop.add_signal_handler(
signal.SIGUSR1,
functools.partial(signal_handler, name='SIGUSR1'),
)
event_loop.add_signal_handler(
signal.SIGINT,
functools.partial(signal_handler, name='SIGINT'),
)
asyncdefsend_signals():
pid=os.getpid()print('开始发送信号给PID:{}'.format(pid))for name in ['SIGHUP', 'SIGHUP', 'SIGUSR1', 'SIGINT']:print('发送信号名字:{}'.format(name))#跟linux 命令kill一样,利用pid结束进程
os.kill(pid, getattr(signal, name))print('放弃控制')
await asyncio.sleep(0.01)return
try:
event_loop.run_until_complete(send_signals())finally:
event_loop.close()
asyncio_signal.py
运行效果
[root@ mnt]# python3 asyncio_signal.py
开始发送信号给PID:78320发送信号名字:SIGHUP
放弃控制
正在处理信号 : SIGHUP
发送信号名字:SIGHUP
放弃控制
正在处理信号 : SIGHUP
发送信号名字:SIGUSR1
放弃控制
正在处理信号 : SIGUSR1
发送信号名字:SIGINT
放弃控制
正在处理信号 : SIGINT
29、协程与线程结合(ThreadPoolExecutor)
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncioimportloggingimportsysimportconcurrent.futuresimporttimedefblocks(n):
log= logging.getLogger('blocks({})'.format(n))
log.info('运行')
time.sleep(0.1)
log.info('done')return n ** 2asyncdefrun_blocking_tasks(executor):"""运行阻塞的任务"""log= logging.getLogger('run_blocking_tasks')
log.info('开始运行')
log.info('创建执行任务')
loop=asyncio.get_event_loop()
blocking_tasks=[
loop.run_in_executor(executor, blocks, i)for i in range(6)
]
log.info('等待执行任务')
completed, pending=await asyncio.wait(blocking_tasks)
results= [t.result() for t incompleted]
log.info('运行结果: {!r}'.format(results))
log.info('exitrun_blocking_tasks 退出')if __name__ == '__main__':
logging.basicConfig(
level=logging.INFO,
format='%(threadName)10s %(name)18s: %(message)s',
stream=sys.stderr
)#创建一个线程池执行器,最大开启3个工作线程
executor =concurrent.futures.ThreadPoolExecutor(
max_workers=3)#创建一个事件循环
event_loop =asyncio.get_event_loop()try:
event_loop.run_until_complete(run_blocking_tasks(executor))finally:
event_loop.close()
asyncio_ThreadPoolExecutor.py
运行效果
[root@ mnt]# python3 asyncio_ThreadPoolExecutor.py
MainThread run_blocking_tasks: 开始运行
MainThread run_blocking_tasks: 创建执行任务
ThreadPoolExecutor-0_0 blocks(0): 运行
ThreadPoolExecutor-0_1 blocks(1): 运行
ThreadPoolExecutor-0_2 blocks(2): 运行
MainThread run_blocking_tasks: 等待执行任务
ThreadPoolExecutor-0_0 blocks(0): doneThreadPoolExecutor-0_0 blocks(3): 运行
ThreadPoolExecutor-0_1 blocks(1): doneThreadPoolExecutor-0_1 blocks(4): 运行
ThreadPoolExecutor-0_2 blocks(2): doneThreadPoolExecutor-0_2 blocks(5): 运行
ThreadPoolExecutor-0_1 blocks(4): doneThreadPoolExecutor-0_0 blocks(3): doneThreadPoolExecutor-0_2 blocks(5): doneMainThread run_blocking_tasks: 运行结果: [0, 9, 16, 25, 1, 4]
MainThread run_blocking_tasks: exitrun_blocking_tasks 退出
30、协程与进程结合(ProcessPoolExecutor)
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncioimportloggingimportsysimportconcurrent.futuresimporttimedefblocks(n):
log= logging.getLogger('blocks({})'.format(n))
log.info('运行')
time.sleep(0.1)
log.info('done')return n ** 2asyncdefrun_blocking_tasks(executor):"""运行阻塞的任务"""log= logging.getLogger('run_blocking_tasks')
log.info('开始运行')
log.info('创建执行任务')
loop=asyncio.get_event_loop()
blocking_tasks=[
loop.run_in_executor(executor, blocks, i)for i in range(6)
]
log.info('等待执行任务')
completed, pending=await asyncio.wait(blocking_tasks)
results= [t.result() for t incompleted]
log.info('运行结果: {!r}'.format(results))
log.info('exitrun_blocking_tasks 退出')if __name__ == '__main__':
logging.basicConfig(
level=logging.INFO,
format='PID %(process)5s %(name)18s: %(message)s',
stream=sys.stderr
)#创建一个线程池执行器,最大开启3个工作线程
executor =concurrent.futures.ProcessPoolExecutor(
max_workers=3)#创建一个事件循环
event_loop =asyncio.get_event_loop()try:
event_loop.run_until_complete(run_blocking_tasks(executor))finally:
event_loop.close()
asyncio_ProcessPoolExecutor.py
运行效果
[root@mnt]# python3 asyncio_ProcessPoolExecutor.py
PID91883run_blocking_tasks: 开始运行
PID91883run_blocking_tasks: 创建执行任务
PID91883run_blocking_tasks: 等待执行任务
PID91884 blocks(0): 运行
PID91885 blocks(1): 运行
PID91886 blocks(2): 运行
PID91884 blocks(0): donePID91884 blocks(3): 运行
PID91886 blocks(2): donePID91885 blocks(1): donePID91886 blocks(4): 运行
PID91885 blocks(5): 运行
PID91884 blocks(3): donePID91886 blocks(4): donePID91885 blocks(5): donePID91883 run_blocking_tasks: 运行结果: [25, 1, 4, 9, 0, 16]
PID91883 run_blocking_tasks: exitrun_blocking_tasks 退出
31、asyncio调试模式的开启
#!/usr/bin/env python#-*- coding: utf-8 -*-
import argparse
import asyncio
import logging
import sys
import time
import warnings#接收命令行
parser =argparse.ArgumentParser('debugging asyncio')
parser.add_argument(
'-v',
dest='verbose',default=False,
action='store_true',
)
args=parser.parse_args()#设置日志级别
logging.basicConfig(
level=logging.DEBUG,
format='%(levelname)7s: %(message)s',
stream=sys.stderr,
)
LOG=logging.getLogger('')
async def inner():
LOG.info('inner 函数开始')
time.sleep(0.1)
LOG.info('inner 运行完成')
async def outer(loop):
LOG.info('outer 函数开始')#ensure_future,直到await才运行
await asyncio.ensure_future(loop.create_task(inner()))
LOG.info('outer 运行完成')
event_loop=asyncio.get_event_loop()ifargs.verbose:
LOG.info('开启DEBUG模式')
event_loop.set_debug(True)#使“慢”任务的阈值非常小以便于说明。默认值为0.1,即100毫秒。
event_loop.slow_callback_duration = 0.001
#在警告过滤器列表中插入一个简单的条目(在前面)。
warnings.simplefilter('always', ResourceWarning)
LOG.info('entering event loop')
event_loop.run_until_complete(outer(event_loop))
asyncio_debug.py
运行效果
#开启Debug
[root@ mnt]# python3 asyncio_debug.py
DEBUG: Using selector: EpollSelector
INFO: entering event loop
INFO: outer 函数开始
INFO: inner 函数开始
INFO: inner 运行完成
INFO: outer 运行完成
[root@python-mysql mnt]# python3 asyncio_debug.py -v
DEBUG: Using selector: EpollSelector
INFO: 开启DEBUG模式
INFO: entering event loop
INFO: outer 函数开始
WARNING: Executing wait_for= cb=[()] created at asyncio_debug.py:42> cb=[_run_until_complete_cb() at /usr/local/Python-3.6.6/lib/python3.6/asyncio/base_events.py:177] created at /usr/local/Python-3.6.6/lib/python3.6/asyncio/base_events.py:447> took 0.003seconds
INFO: inner 函数开始
INFO: inner 运行完成
WARNING: Executing result=None created at asyncio_debug.py:42> took 0.101seconds
INFO: outer 运行完成
#正常运行
[root@ mnt]# python3 asyncio_debug.py
DEBUG: Using selector: EpollSelector
INFO: entering event loop
INFO: outer 函数开始
INFO: inner 函数开始
INFO: inner 运行完成
INFO: outer 运行完成
You have new mailin /var/spool/mail/root
32、利用生成器的方式,创建协程socket监听
#!/usr/bin/env python#-*- coding: utf-8 -*-
importasyncioimportloggingimportsys
@asyncio.coroutinedefecho(reader, writer):
address= writer.get_extra_info('peername')
log= logging.getLogger('echo_{}_{}'.format(*address))
log.debug('connection accepted')whileTrue:
data= yield from reader.read(128)ifdata:
log.debug('received {!r}'.format(data))
writer.write(data)yield fromwriter.drain()
log.debug('sent {!r}'.format(data))else:
log.debug('closing')
writer.close()return
#开启Debug模式
logging.basicConfig(
level=logging.DEBUG,
format='%(name)s: %(message)s',
stream=sys.stderr,
)#设置日志的title
log = logging.getLogger('main')#设置开启服务的IP+端口
server_address = ('localhost', 8888)#获取事件循环
event_loop =asyncio.get_event_loop()#创建服务器,让循环在之前完成协同工作。并且启动实际事件循环
coroutine = asyncio.start_server(echo, *server_address,loop=event_loop)
server=event_loop.run_until_complete(coroutine)
log.debug('starting up on {} port {}'.format(*server_address))try:#开启一直循环处理任务
event_loop.run_forever()finally:#结束后清理的工作
log.debug('closing server')
server.close()
event_loop.run_until_complete(server.wait_closed())
log.debug('closing event loop')
event_loop.close()
asyncio_echo_server_generator
运行效果
[root@ mnt]# python3 asyncio_echo_server_generator
asyncio: Using selector: EpollSelector
main: starting up on localhost port8888
33、协程的关闭示例
importasyncioimportloggingimportsys
logging.basicConfig(
level=logging.DEBUG,
format='%(name)s: %(message)s',
stream=sys.stderr,
)
LOG= logging.getLogger('main')
asyncdefstopper(loop):
LOG.debug('stopper invoked')
loop.stop()
event_loop=asyncio.get_event_loop()
event_loop.create_task(stopper(event_loop))try:
LOG.debug('entering event loop')
event_loop.run_forever()finally:
LOG.debug('closing event loop')
event_loop.close()
asyncio_stop.py
运行效果
[root@ mnt]# python3 asyncio_stop.py
asyncio: Using selector: EpollSelector
main: entering event loop
main: stopper invoked
main: closing event loop