asyncio

asyncio是python用於解決異步io編程的一整套解決方案

1.使用asyncio

import asyncio
import time
async def get_html(url):
    print("start get url")
    await asyncio.sleep(2)   # 耗時操做 要加await
    print("end get url")

if __name__ == "__main__":
    start_time = time.time()
    loop = asyncio.get_event_loop()  # 建立event_loop 對象    若是要建立新的event_loop對象 須要使用asyncio.new_event_loop()
    tasks = [get_html("http://www.imooc.com") for i in range(10)]
    loop.run_until_complete(asyncio.wait(tasks))   # run_until_complete() 啓動協程  asyncio.wait(tasks) 循環多個asyncis.wait(可迭代對象,啓動多個對象)
    loop.run_until_complete(asyncio.gather(tasks))
    print(time.time()-start_time)

# gather和wait的區別
# gather比wait更加高一級   推薦使用gather
    group1 = [get_html("http://projectsedu.com") for i in range(2)]
    group2 = [get_html("http://www.imooc.com") for i in range(2)]
    group1 = asyncio.gather(*group1)
    group2 = asyncio.gather(*group2)
    group2.cancel()
    loop.run_until_complete(asyncio.gather(group1, group2))
    print(time.time() - start_time)

# 結果     能夠在2秒能完成全部的併發
start get url
start get url
start get url
start get url
start get url
start get url
start get url
start get url
start get url
start get url
end get url
end get url
end get url
end get url
end get url
end get url
end get url
end get url
end get url
end get url
2.003009080886841

2.獲取協程的返回值,函數完成時回調

import asyncio
import time
from functools import partial


async def get_html(url):
    print("start get url")
    await asyncio.sleep(2)
    return "bobby"


def callback(url, future):
    print(url)
    print("send email to bobby")


if __name__ == "__main__":
    start_time = time.time()
    loop = asyncio.get_event_loop()   # asyncio.get_event_loop方法能夠建立一個事件循環 建立event_loop 對象    若是要建立新的event_loop對象 須要使用asyncio.new_event_loop()
    # get_future = asyncio.ensure_future(get_html("http://www.imooc.com"))
    task = loop.create_task(get_html("http://www.imooc.com"))   # asyncio.ensure_future 和 loop.create_task均可以建立一個task,   任務對象task    實際上是run_until_complete方法將協程包裝成爲了一個任務(task)對象。所謂task對象是Future類的子類。保存了協程運行後的狀態,用於將來獲取協程的結果。
    task.add_done_callback(partial(callback, "http://www.imooc.com"))  # add_done_callback 執行函數的回調   partial能夠給回調函數添加參數
    loop.run_until_complete(task)  # run_until_complete將協程註冊到事件循環,並啓動事件循環
    print(task.result())   # task.result() 獲取task返回值

3.取消future(task)

import asyncio
import time


async def get_html(sleep_times):
    print("waiting")
    await asyncio.sleep(sleep_times)
    print("done after {}s".format(sleep_times))


if __name__ == "__main__":
    task1 = get_html(2)
    task2 = get_html(3)
    task3 = get_html(3)

    tasks = [task1, task2, task3]

    loop = asyncio.get_event_loop()

    try:
        loop.run_until_complete(asyncio.wait(tasks))
    except KeyboardInterrupt as e:
        all_tasks = asyncio.Task.all_tasks()  # asyncio.Task.all_tasks()  獲取全部的 tasks
        for task in all_tasks:
            print("cancel task")
            print(task.cancel())  # # 取消成功返回True,取消失敗返回False
        loop.stop()  # 中止時間循環
        loop.run_forever()   # 從新啓動事件循環   註釋會拋異常
    finally:
        loop.close()

4.協程裏面嵌套協程

import asyncio


async def compute(x, y):
    print('Compute %s + %s .....' % (x, y))
    await asyncio.sleep(1.0)
    return x + y


async def print_sum(x, y):
    result = await compute(x, y)
    print('%s + %s =%s' % (x, y, result))


loop = asyncio.get_event_loop()
loop.run_until_complete(print_sum(1, 2))
loop.close()

 

5.call_soon  下個循環當即執行

import asyncio


def callback(sleep_time):
    print('sleep {} success'.format(sleep_time))


def stoploop(loop):
    loop.stop()


if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.call_soon(callback, 2)  # 下個循環當即執行
    loop.call_soon(stoploop, loop)
    loop.run_forever()
    loop.close() 

6.call_later   多少秒以後執行

import asyncio


def callback(sleep_time):
    print('sleep {} success'.format(sleep_time))


def stoploop(loop):
    loop.stop()


if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.call_later(2, callback, 2.0)  # 2秒以後運行
    loop.call_later(1, callback, 1.0)  # 1秒以後運行
    loop.call_later(3, callback, 3.0)  # 3秒以後運行
    loop.run_forever()
    loop.close()

# 結果
sleep 1.0 success
sleep 2.0 success
sleep 3.0 success
相關文章
相關標籤/搜索