1. 程式人生 > >Python學習---Python的異步---asyncio模塊(no-http)

Python學習---Python的異步---asyncio模塊(no-http)

time inf images ron block 實現 服務 true rip

Asyncio進行異步IO請求操作:

1. @asyncio.coroutine 裝飾任務函數

2. 函數內配合yield from 和裝飾器@asyncio.coroutine 配合使用【固定格式】

3. loop = asyncio.get_event_loop()

loop.run_until_complete(asyncio.gather(*tasks)) # 接受異步IO的任務並異步執行任務

實例一:

異步IO: 協程機制 + 回調函數

import asyncio

@asyncio.coroutine  # 裝飾任務函數
def func1():
    print(‘before...func1......‘)
    # yield from 和裝飾器@asyncio.coroutine 配合使用【固定格式】
    yield from asyncio.sleep(5)  # 必須寫asyncio才表示異步IO執行5秒,time.sleep(5)不生效
    print(‘5秒後...‘)
    print(‘end...func1......‘)

tasks = [func1(), func1()]
# 事件循環: 對涉及異步,協成,阻塞等IO操作時進行事件的循環操作
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(*tasks)) # 接受異步IO的任務並異步執行任務
loop.close()

技術分享圖片

AsyncIO缺點:

不支持HTTP請求,也就是說不能直接發送URL過去進行訪問

支持TCP請求,也就是說可以發送【IP+端】進行訪問

註:HTTP在TCP之上

基於asyncio實現利用TCP模擬HTTP請求

import asyncio
# 基於asyncio實現利用TCP模擬HTTP請求[asyncio實際上不支持HTTP請求]
@asyncio.coroutine
def fetch_async(host, url=‘/‘):
    print(‘HOST和URL信息:‘, host, url)
    # reader: 用於讀取連接的信息
    # writer: 用於給服務器寫信息
    reader, writer = yield from asyncio.open_connection(host, 80)
    # 基於TCP模擬的HTTP請求:請求頭header和請求體body之間是2空行【\r\n\r\n】分隔的
    request_header_content = """GET %s HTTP/1.0\r\nHost: %s\r\n\r\n""" % (url, host,)
    request_header_content = bytes(request_header_content, encoding=‘utf-8‘) # 字符串轉換字節

    writer.write(request_header_content) # 準備發送數據給服務器
    # drain: 英文翻譯為喝光,這裏作發送完成理解
    yield from writer.drain() # 發送數據給服務器,此時可能會阻塞執行個請求,考慮數據量大等原因
    text = yield from reader.read() # 等待返回的數據,text就是先收到回復的請求完成後等待其他返回
    print(host,url,‘返回後的結果:‘, text)
    writer.close() # 關閉流

tasks = [
    fetch_async(‘www.cnblogs.com‘, ‘/ftl1012/‘),
    fetch_async(‘www.dig.chouti.com‘, ‘/images/homepage_download.png‘)
]

loop = asyncio.get_event_loop()
results = loop.run_until_complete(asyncio.gather(*tasks))
loop.close()

技術分享圖片

基於TCP模擬HTTP詳解:

技術分享圖片

Python學習---Python的異步---asyncio模塊(no-http)