程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

python協程初體驗

編輯:Python

前言

在了解了Python並發編程的多線程和多進程之後,我們來了解一下基於asyncio的異步IO編程 => 協程

協程

協程(Coroutine)又稱微線程、纖程,協程不是進程或線程,其執行過程類似於 Python 函數調用,Python 的 asyncio 模塊實現的異步IO編程框架中,協程是對使用 async 關鍵字定義的異步函數的調用

一個進程包含多個線程,類似於一個人體組織有多種細胞在工作,同樣,一個程序可以包含多個協程。多個線程相對獨立,線程的切換受系統控制。同樣,多個協程也相對獨立,但是其切換由程序自己控制

那協程有什麼優勢呢?

  • 執行效率極高,因為子程序切換(函數)不是線程切換,由程序自身控制,沒有切換線程的開銷。所以與多線程相比,線程的數量越多,協程性能的優勢越明顯
  • 不需要多線程的鎖機制,因為只有一個線程,也不存在同時寫變量沖突,在控制共享資源時也不需要加鎖,因此執行效率高很多

Python3.x協程

Python3.x還提供了如下方式實現協程:asyncio + yield from (python3.4+) asyncio + async/await (python3.5+)

Python3.4以後引入了asyncio模塊,可以很好的支持協程

asyncio

evnt_loop: 事件循環,相當於一個無限循環,我們可以把一些函數注冊到這個事件循環上,當滿足條件發生的時候,就會調用對應的處理方法

coroutine: 中文翻譯叫協程,在 Python 中常指代為協程對象類型,我們可以將協程對象注冊到時間循環中,它會被事件循環調用。我們可以使用 async 關鍵字來定義一個方法,這個方法在調用時不會立即被執行,而是返回一個協程對象

task: 任務,它是對協程對象的進一步封裝,包含了任務的各個狀態

future: 代表將來執行或沒有執行的任務的結果,實際上和 task 沒有本質區別

async

定義異步函數

async def async_function():
print('Number:', 1)
return 1
print(async_function())
輸出:
返回一個協程對象
<coroutine object async_function at 0x10a4b0f10>

調用send方法激活

print(async_function().send(None))

異步函數

async def async_function():
print('Number:', 1)
r = requests.get('http://www.baidu.com')
return r
coroutine = async_function()
loop = asyncio.get_event_loop()
t = loop.run_until_complete(coroutine)
print(t)
print('After calling loop')

異步函數task

coroutine = async_function()
loop = asyncio.get_event_loop()
task = loop.create_task(coroutine)
print('Task:', task)
loop.run_until_complete(task)
print('Task:', task)
print('After calling loop')
輸出: coroutine 對象多了運行狀態,比如 running、finished 等
Task: <Task pending coro=<async_function() running at async_t.py:104>>
Number: 1
Task: <Task finished coro=<async_function() done, defined at async_t.py:104> result=<Response [200]>>
After calling loop

異步函數ensure_future

task = asyncio.ensure_future(coroutine)
print('Task:', task)
loop = asyncio.get_event_loop()
loop.run_until_complete(task)
print('Task:', task)
print('After calling loop')

異步函數綁定回調

async def async_function():
print('Number:', 1)
r = requests.get('http://www.baidu.com')
return r
def callback(task):
print('Status:', task.result())
task = asyncio.ensure_future(coroutine)
task.add_done_callback(callback)
print('Task:', task)
loop = asyncio.get_event_loop()
loop.run_until_complete(task)
print('Task:', task)

異步函數網絡並發執行

import requests_async as requests
async def post_requests():
print("Hello world!")
async with requests.Session() as session:
print("create Session statr")
response = await session.get('https://example.org')
print("create Session over")
print(response.status_code)
# print(response.text)
tasks = [post_requests() for host in ['www.sina.com.cn', 'www.sohu.com', 'www.163.com']]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
print('Task:', tasks)

異步函數網絡請求

async def get(url):
return requests.get(url)
async def request():
url = 'http://127.0.0.1:5000/api'
print('Waiting for', url)
response = await get(url)
print('Get response from', url, 'Result:', response.text)
tasks = [asyncio.ensure_future(request()) for _ in range(5)]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

多任務異步

import asyncio
import requests
async def request():
url = 'https://www.baidu.com'
status = requests.get(url)
return status
tasks = [asyncio.ensure_future(request()) for _ in range(5)]
print('Tasks:', tasks)
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
for task in tasks:
print('Task Result:', task.result())

aiohttp異步請求

async def aiohttp_get():
url = 'http://127.0.0.1:5000/api'
print('Waiting for', url)
session = aiohttp.ClientSession()
response = await session.get(url)
result = await response.text()
print('Get response from', url)
session.close()
return result
tasks = [asyncio.ensure_future(aiohttp_get()) for _ in range(5)]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

結尾

上面就是python協程的一些簡單體驗,後續會結合一些協程實戰項目,分享更多使的技巧~


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved