#coding=utf-8
'''
Created on 2018年3月19日
@author: BH Wong
'''
'''
概念性知识:GIL(全局锁)的存在,使得多线程成了鸡肋。
既然在GIL之下,同一时刻只能有一个线程在运行,那么对于CPU密集的程序来说,线程之间的切换开销就成了拖累,
而以I/O为瓶颈的程序正是协程所擅长的。
协程:多任务并发(非并行),每个任务在合适的时候挂起(发起I/O)和恢复(I/O结束)
协程经历的三个阶段:
最初的生成器变形yield/send
引入@asyncio.coroutine和yield from
在最近的Python3.5版本中引入async/await关键字
这里只将第三阶段,封装好了的async/await。
前两阶段参考:http://python.jobbole.com/86069/,里面原理性的东西说的很详细。有空的话需再回头看看。
流程:
(1)使用async def 定义协程函数 ,应 >=1
(2)在async def 中用await asyncio.sleep()定义函数休眠时间。
#########定义好函数##############
(3) loop = asyncio.get_event_loop()
tasks = [
asyncio.ensure_future(func1),
asyncio.ensure_future(func2),
]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
涉及模块:
'''
import asyncio
import random
import time
async def smart_fib(n):
index = 0
a = 0
b = 1
while index < n:
sleep_secs = random.uniform(0, 0.2)
await asyncio.sleep(sleep_secs)
print('Smart one think {} secs to get {}'.format(sleep_secs, b))
a, b = b, a + b
index += 1
async def stupid_fib(n):
index = 0
a = 0
b = 1
while index < n:
sleep_secs = random.uniform(0, 0.4)
await asyncio.sleep(sleep_secs)
print('Stupid one think {} secs to get {}'.format(sleep_secs, b))
a, b = b, a + b
index += 1
##################################
def smart_fib1(n):
index = 0
a = 0
b = 1
while index < n:
sleep_secs = random.uniform(0, 0.2)
time.sleep(sleep_secs)
print('Smart one think {} secs to get {}'.format(sleep_secs, b))
a, b = b, a + b
index += 1
def stupid_fib1(n):
index = 0
a = 0
b = 1
while index < n:
sleep_secs = random.uniform(0, 0.4)
time.sleep(sleep_secs)
print('Stupid one think {} secs to get {}'.format(sleep_secs, b))
a, b = b, a + b
index += 1
if __name__ == '__main__':
#async await 方式执行
time_start = time.time()
loop = asyncio.get_event_loop()
tasks = [
asyncio.ensure_future(smart_fib(10)),
asyncio.ensure_future(stupid_fib(10)),
]
loop.run_until_complete(asyncio.wait(tasks))
print('All fib finished.')
loop.close()
time_end = time.time()
print('first:',time_end-time_start)
#顺序执行
time_start = time.time()
smart_fib1(10)
stupid_fib1(10)
time_end = time.time()
print('second:',time_end-time_start)