Skip to content

Instantly share code, notes, and snippets.

@Jerry0420
Last active July 30, 2020 02:45
Show Gist options
  • Save Jerry0420/d5e578faae00b133c676847a167d80a0 to your computer and use it in GitHub Desktop.
Save Jerry0420/d5e578faae00b133c676847a167d80a0 to your computer and use it in GitHub Desktop.
import requests
import time
import asyncio
import functools
# async IO is a single-threaded, single-process design
# event_loop
# coroutine
# task
# future
now = lambda : time.time()
# coroutine function
async def do_some_work(x):
print('Waiting: ', x)
return "hello world"
start = now()
# coroutine object
coroutine = do_some_work(2)
loop = asyncio.get_event_loop()
loop.run_until_complete(coroutine)
print('TIME: ', now() - start)
print('====================================================')
start = now()
coroutine = do_some_work(2)
loop = asyncio.get_event_loop()
# ensure_future, create_task 皆是產生 task
# task = asyncio.ensure_future(coroutine)
task = loop.create_task(coroutine)
print(task) # pending
# run_until_complete 放入 task or coroutine object 皆可,內部都會轉成 task
loop.run_until_complete(task)
print(task) #finished
print('TIME: ', now() - start)
print('====================================================')
def callback(t, future):
print('In Callback:', t, future.result())
start = now()
coroutine = do_some_work(2)
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(coroutine)
# task.add_done_callback(callback)
task.add_done_callback(functools.partial(callback, 2))
loop.run_until_complete(task)
# 取出 coroutine function 的 return value
print('Task ret: {}'.format(task.result()))
print('TIME: ', now() - start)
print('====================================================')
async def do_some_work(x):
print('Waiting: ', x)
await asyncio.sleep(x)
return 'Done after {}s'.format(x)
start = now()
coroutine = do_some_work(2)
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(coroutine)
loop.run_until_complete(task)
print('Task ret: ', task.result())
print('TIME: ', now() - start)
print('====================================================')
start = now()
coroutine1 = do_some_work(1)
coroutine2 = do_some_work(2)
coroutine3 = do_some_work(2)
tasks = [
asyncio.ensure_future(coroutine1),
asyncio.ensure_future(coroutine2),
asyncio.ensure_future(coroutine3)
]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
for task in tasks:
print('Task ret: ', task.result())
# 2s 完成
print('TIME: ', now() - start)
print('====================================================')
async def main():
coroutine1 = do_some_work(1)
coroutine2 = do_some_work(2)
coroutine3 = do_some_work(2)
tasks = [
asyncio.ensure_future(coroutine1),
asyncio.ensure_future(coroutine2),
asyncio.ensure_future(coroutine3)
]
# 第一種寫法
# dones, pendings = await asyncio.wait(tasks)
# for task in dones:
# print('Task ret: ', task.result())
# 第二種寫法
res = await asyncio.gather(*tasks)
for task in res:
print('Task ret: ', task)
# 第三種寫法
# return await asyncio.wait(tasks)
start = now()
# 第一, 二種寫法
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
# 第三種寫法
# done, pending = loop.run_until_complete(main())
# for task in done:
# print('Task ret: ', task.result())
print('TIME: ', now() - start)
print('====================================================')
url = 'https://www.google.com.tw/'
loop = asyncio.get_event_loop()
start_time = time.time()
async def send_req(url):
t = time.time()
print("Send a request at",t-start_time,"seconds.")
res = await loop.run_in_executor(None, requests.get, url)
t = time.time()
print("Receive a response at",t-start_time,"seconds.")
return res
tasks = []
for i in range(3):
task = loop.create_task(send_req(url))
tasks.append(task)
done, pending = loop.run_until_complete(asyncio.wait(tasks))
for i in done:
print(i.result())
print('====================================================')
loop = asyncio.get_event_loop()
async def example1():
print("Start example1 coroutin.")
await asyncio.sleep(1)
print("Finish example1 coroutin.")
async def example2():
print("Start example2 coroutin.")
# do some process...
print("Finish example2 coroutin.")
# 把 coroutine 封裝成一個 task, 才能真正執行
tasks = [
asyncio.ensure_future(example1()),
asyncio.ensure_future(example2()),
]
# 多個 tasks 用 asyncio.wait
loop.run_until_complete(asyncio.wait(tasks))
print('====================================================')
async def func():
print('func start')
await asyncio.sleep(1)
print('func end')
return "hello"
loop = asyncio.get_event_loop() # 建立一個Event loop
print(func) # 原本是一個coroutine function
obj=func()
print(obj) # 執行之後回傳一個coroutine object
# 以下兩者皆是產生 task
# task = asyncio.ensure_future(obj)
task = loop.create_task(obj)
print(task) # 經過ensure_future包裝成一個Future對象(也可以說是一個Task對象)
# 一個 task, 直接放入
loop.run_until_complete(task) # 在此放 task or func(), 皆可以
loop.run_until_complete(func())
print('====================================================')
#asyncio design pattern: 用一個 async function 把所有 async func 包起來,一次一起執行
loop = asyncio.get_event_loop()
async def bar():
# 一個任務要執行時
# result = await func()
# return result
task1 = loop.create_task(func()) #asyncio.ensure_future
task2 = loop.create_task(func()) #asyncio.ensure_future
# 以下兩種情況,會等待 task1, task2 一起完成,才會繼續下去
# 多個任務要執行時
# result = await asyncio.gather(task1, task2)
# return result
# 多個任務要執行時
done, pending = await asyncio.wait([task1, task2])
return [i.result() for i in done]
result = loop.run_until_complete(bar())
print(result)
def bar():
task1 = asyncio.ensure_future(func())
task2 = asyncio.ensure_future(func())
# 以下情況, task1, task2 先完成的,就會先丟出去
# 多個任務要執行時
for response in asyncio.as_completed([task1, task2]):
yield response
results = bar()
loop = asyncio.get_event_loop()
for result in results:
final = loop.run_until_complete(result)
print(final)
print('====================================================')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment