最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

python協(xié)程實(shí)現(xiàn)高并發(fā)的技術(shù)詳解

 更新時(shí)間:2025年11月21日 15:42:51   作者:東方佑  
協(xié)程是實(shí)現(xiàn)高并發(fā)的一種非常高效的方式,特別適合處理大量I/O操作的場(chǎng)景,本文我們將簡(jiǎn)單介紹python協(xié)程實(shí)現(xiàn)高并發(fā)的相關(guān)方法,需要的小伙伴可以了解下

協(xié)程是實(shí)現(xiàn)高并發(fā)的一種非常高效的方式,特別適合處理大量I/O操作(如網(wǎng)絡(luò)請(qǐng)求、文件操作)的場(chǎng)景。它通過在單個(gè)線程內(nèi)實(shí)現(xiàn)多個(gè)任務(wù)的切換來避免阻塞,從而最大限度地利用CPU資源。

核心概念與簡(jiǎn)單示例

要理解協(xié)程如何實(shí)現(xiàn)高并發(fā),首先要明白幾個(gè)關(guān)鍵概念:

  • 協(xié)程(Coroutine):一種輕量級(jí)的“微線程”,可以在執(zhí)行過程中暫停(await)并在適當(dāng)?shù)臅r(shí)候恢復(fù),而不是像普通函數(shù)那樣一次性執(zhí)行完畢。這種可掛起的能力是高并發(fā)的基石。
  • 事件循環(huán)(Event Loop):這是協(xié)程的“大腦”或調(diào)度中心。它負(fù)責(zé)在單個(gè)線程中調(diào)度和執(zhí)行多個(gè)協(xié)程任務(wù)。當(dāng)一個(gè)協(xié)程因等待I/O(比如網(wǎng)絡(luò)響應(yīng))而暫停時(shí),事件循環(huán)會(huì)立刻切換到另一個(gè)就緒的協(xié)程去執(zhí)行,從而避免了CPU的空等。
  • async/await 關(guān)鍵字:async 用于聲明一個(gè)函數(shù)是異步函數(shù)(即協(xié)程),await 用于在協(xié)程內(nèi)部掛起自身,直到其后面的異步操作完成。

下面是一個(gè)簡(jiǎn)單的例子,演示了如何使用 asyncio 庫(kù)創(chuàng)建兩個(gè)協(xié)程,讓它們“并發(fā)”地執(zhí)行:

import asyncio
import time

async def say_after(delay, what):
    await asyncio.sleep(delay)  # 模擬一個(gè)耗時(shí)的I/O操作
    print(what)

async def main():
    print(f"程序開始于: {time.strftime('%X')}")

    # 使用 asyncio.gather 來并發(fā)運(yùn)行兩個(gè)協(xié)程
    await asyncio.gather(
        say_after(2, 'Hello,'),
        say_after(1, 'World!')
    )

    print(f"程序結(jié)束于: {time.strftime('%X')}")

# 運(yùn)行主協(xié)程
asyncio.run(main())

在這個(gè)例子中,雖然 Hello, 任務(wù)設(shè)定等待2秒,而 World! 任務(wù)只等待1秒,但由于它們是并發(fā)執(zhí)行的,總耗時(shí)大約只有2秒,而不是順序執(zhí)行時(shí)的3秒。輸出將會(huì)是:

程序開始于: 12:00:00
World!
Hello,
程序結(jié)束于: 12:00:02

高并發(fā)實(shí)踐:網(wǎng)絡(luò)請(qǐng)求

協(xié)程的真正威力體現(xiàn)在處理成千上萬個(gè)網(wǎng)絡(luò)請(qǐng)求時(shí)。下面的例子展示了如何使用 aiohttp 庫(kù)異步地并發(fā)獲取多個(gè)網(wǎng)頁(yè)內(nèi)容。

import asyncio
import aiohttp
import time

async def fetch_url(session, url):
    async with session.get(url) as response:
        # 注意:在實(shí)際項(xiàng)目中,對(duì)于大響應(yīng)體,應(yīng)使用 response.content.read(chunk_size) 流式讀取
        html = await response.text()
        print(f"從 {url} 獲取了 {len(html)} 個(gè)字符")

async def main():
    urls = [
        'https://www.python.org',
        'https://www.example.com',
        'https://httpbin.org/get',
        # ... 可以添加更多URL
    ]

    # 關(guān)鍵:在整個(gè)抓取會(huì)話期間,復(fù)用同一個(gè) ClientSession 實(shí)例
    # 其內(nèi)部維護(hù)了一個(gè)連接池,可以復(fù)用TCP連接,極大提升性能
    async with aiohttp.ClientSession() as session:
        tasks = []
        for url in urls:
            # 為每個(gè)URL創(chuàng)建一個(gè)協(xié)程任務(wù)
            task = asyncio.create_task(fetch_url(session, url))
            tasks.append(task)

        # 等待所有任務(wù)完成
        await asyncio.gather(*tasks)

# 記錄耗時(shí)
start_time = time.time()
asyncio.run(main())
end_time = time.time()
print(f"總共耗時(shí): {end_time - start_time:.2f} 秒")

這個(gè)程序幾乎在同一時(shí)間發(fā)起所有請(qǐng)求,總耗時(shí)基本等于最慢的那個(gè)請(qǐng)求的耗時(shí),而不是所有請(qǐng)求耗時(shí)的總和。

協(xié)程如何實(shí)現(xiàn)高并發(fā):核心技術(shù)

協(xié)程實(shí)現(xiàn)高并發(fā)主要依賴于以下兩點(diǎn):

協(xié)作式多任務(wù)與事件循環(huán)

協(xié)程是協(xié)作式的,這意味著它們會(huì)主動(dòng)在可能發(fā)生阻塞的地方(即 await 處)掛起自己,將控制權(quán)交還給事件循環(huán)。事件循環(huán)則不斷地檢查:有哪些I/O操作已經(jīng)完成了?哪些協(xié)程可以恢復(fù)了?然后調(diào)度執(zhí)行那些就緒的協(xié)程。這個(gè)過程在單線程內(nèi)完成,完全避免了多線程帶來的鎖競(jìng)爭(zhēng)和上下文切換的開銷。

非阻塞I/O與連接池

協(xié)程需要與非阻塞的I/O系統(tǒng)調(diào)用配合才能發(fā)揮最大效能。像 aiohttp 這樣的庫(kù)在底層使用了操作系統(tǒng)的非阻塞I/O機(jī)制(如Linux的 epoll)。當(dāng)一個(gè)協(xié)程發(fā)起網(wǎng)絡(luò)請(qǐng)求時(shí),這個(gè)請(qǐng)求會(huì)以非阻塞方式立即發(fā)出,然后協(xié)程掛起。事件循環(huán)則通過I/O多路復(fù)用機(jī)制(如 select, poll, epoll)來監(jiān)聽大量socket(網(wǎng)絡(luò)連接)的狀態(tài),一旦某個(gè)socket的數(shù)據(jù)準(zhǔn)備好了,事件循環(huán)就會(huì)喚醒等待該socket的協(xié)程繼續(xù)執(zhí)行。同時(shí),如第一個(gè)搜索結(jié)果強(qiáng)調(diào)的,連接池(Connection Pool) 也至關(guān)重要。通過復(fù)用已經(jīng)建立的TCP連接,可以避免為每個(gè)請(qǐng)求都進(jìn)行耗時(shí)的TCP三次握手,這在高并發(fā)下能帶來數(shù)量級(jí)的性能提升。

協(xié)程、多線程與多進(jìn)程的對(duì)比

理解協(xié)程的適用場(chǎng)景很重要,下面的表格對(duì)比了三種主要的并發(fā)方式:

特性協(xié)程 (Coroutine)多線程 (Threading)多進(jìn)程 (Multiprocessing)
運(yùn)行模型單線程內(nèi)協(xié)作式切換操作系統(tǒng)線程,搶占式調(diào)度獨(dú)立的操作系統(tǒng)進(jìn)程
數(shù)據(jù)共享共享內(nèi)存,無需加鎖(但需注意任務(wù)內(nèi)狀態(tài))共享內(nèi)存,需處理線程安全(如鎖)內(nèi)存不共享,需通過IPC(如隊(duì)列)
開銷極小,可輕松創(chuàng)建數(shù)萬協(xié)程較大,線程數(shù)受限于內(nèi)存和上下文切換成本巨大,進(jìn)程數(shù)通常與CPU核數(shù)相關(guān)
最佳場(chǎng)景I/O密集型任務(wù)(網(wǎng)絡(luò)、文件讀寫)I/O密集型任務(wù)(但協(xié)程通常更高效)CPU密集型任務(wù)(計(jì)算、圖像處理)
編程復(fù)雜度中等(需理解 async/await)高(需處理復(fù)雜的同步問題)中高(需處理進(jìn)程間通信)

簡(jiǎn)單來說:

I/O密集型(任務(wù)大部分時(shí)間在等待):協(xié)程 >> 多線程 > 多進(jìn)程

CPU密集型(任務(wù)大部分時(shí)間在計(jì)算):多進(jìn)程 > 多線程/協(xié)程(由于Python的GIL,計(jì)算密集型任務(wù)在多線程中無法真正并行)

實(shí)踐建議與常見誤區(qū)

避免在協(xié)程中調(diào)用阻塞性代碼:不要在協(xié)程內(nèi)使用 time.sleep(1) 或同步的 requests.get()。這會(huì)阻塞整個(gè)事件循環(huán),使并發(fā)失效。務(wù)必使用對(duì)應(yīng)的異步版本 await asyncio.sleep(1) 和 aiohttp。

使用信號(hào)量(Semaphore)控制并發(fā)度:雖然協(xié)程很輕量,但向同一個(gè)目標(biāo)服務(wù)器發(fā)起無限度的并發(fā)請(qǐng)求可能會(huì)被視為攻擊或?qū)е聦?duì)方服務(wù)不可用??梢允褂?asyncio.Semaphore 來限制最大并發(fā)數(shù)。

復(fù)用對(duì)象:如網(wǎng)絡(luò)請(qǐng)求的例子所示,在整個(gè)應(yīng)用生命周期內(nèi)復(fù)用 ClientSession 這樣的對(duì)象,以利用連接池。

組合使用多種并發(fā)模型:對(duì)于更復(fù)雜的場(chǎng)景,可以采用“多進(jìn)程+協(xié)程”的混合模式。例如,用多進(jìn)程利用多核CPU,在每個(gè)進(jìn)程內(nèi)部使用協(xié)程處理高并發(fā)的I/O。

到此這篇關(guān)于python協(xié)程實(shí)現(xiàn)高并發(fā)的技術(shù)詳解的文章就介紹到這了,更多相關(guān)python協(xié)程高并發(fā)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • windows系統(tǒng)下Boost.Python的配置和使用方法(新手教學(xué))

    windows系統(tǒng)下Boost.Python的配置和使用方法(新手教學(xué))

    Boost.Python是Boost庫(kù)的一部分,Boost庫(kù)本身包含了許多其他有用的庫(kù),這篇文章主要介紹了windows系統(tǒng)下Boost.Python的配置和使用方法的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2026-01-01
  • Python Numpy運(yùn)行報(bào)錯(cuò):IndexError: too many indices for array的分析及解決

    Python Numpy運(yùn)行報(bào)錯(cuò):IndexError: too many in

    在使用Numpy進(jìn)行數(shù)組操作時(shí),經(jīng)常會(huì)遇到各種錯(cuò)誤,其中,IndexError: too many indices for array是一種常見的錯(cuò)誤,它通常發(fā)生在嘗試使用一個(gè)過多維度的索引來訪問一個(gè)較低維度的數(shù)組時(shí),本文介紹了Python Numpy報(bào)錯(cuò)的解決辦法,需要的朋友可以參考下
    2024-07-07
  • Python configparser模塊配置文件解析與應(yīng)用探究

    Python configparser模塊配置文件解析與應(yīng)用探究

    在Python中,configparser模塊是用于處理配置文件的重要工具,本文將全面探討configparser模塊的使用方法,包括讀取、修改、寫入配置文件,以及如何在實(shí)際項(xiàng)目中應(yīng)用該模塊,結(jié)合豐富的示例代碼,將深入剖析該模塊的功能和靈活性
    2024-01-01
  • 在numpy矩陣中令小于0的元素改為0的實(shí)例

    在numpy矩陣中令小于0的元素改為0的實(shí)例

    今天小編就為大家分享一篇在numpy矩陣中令小于0的元素改為0的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • 詳解Windows下源碼編譯PaddlePaddle

    詳解Windows下源碼編譯PaddlePaddle

    這篇文章主要為大家介紹了Windows下從源碼編譯PaddlePaddle解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • Python Django路徑配置實(shí)現(xiàn)過程解析

    Python Django路徑配置實(shí)現(xiàn)過程解析

    這篇文章主要介紹了Python Django路徑配置實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • Conda創(chuàng)建新環(huán)境的詳細(xì)圖文教程

    Conda創(chuàng)建新環(huán)境的詳細(xì)圖文教程

    Anaconda功能龐大,其可以理解為一個(gè)工具,也是一個(gè)可執(zhí)行命令,下面這篇文章主要給大家介紹了關(guān)于Conda創(chuàng)建新環(huán)境的詳細(xì)圖文教程,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-01-01
  • Python+matplotlib實(shí)現(xiàn)餅圖的繪制

    Python+matplotlib實(shí)現(xiàn)餅圖的繪制

    Matplotlib是一個(gè)Python的2D繪圖庫(kù),它以各種硬拷貝格式和跨平臺(tái)的交互式環(huán)境生成出版質(zhì)量級(jí)別的圖形。本文將利用Matplotlib庫(kù)繪制餅圖,感興趣的可以了解一下
    2022-03-03
  • Python使用textcase庫(kù)輕松實(shí)現(xiàn)文本格式處理

    Python使用textcase庫(kù)輕松實(shí)現(xiàn)文本格式處理

    在Python開發(fā)中,規(guī)范的文本格式處理是提升代碼可讀性和維護(hù)性的關(guān)鍵一環(huán),本文將系統(tǒng)講解textcase庫(kù)的核心功能,典型應(yīng)用場(chǎng)景及性能優(yōu)化策略,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-04-04
  • 安裝ElasticSearch搜索工具并配置Python驅(qū)動(dòng)的方法

    安裝ElasticSearch搜索工具并配置Python驅(qū)動(dòng)的方法

    這篇文章主要介紹了安裝ElasticSearch搜索工具并配置Python驅(qū)動(dòng)的方法,文中還介紹了其與Kibana數(shù)據(jù)顯示客戶端的配合使用,需要的朋友可以參考下
    2015-12-12

最新評(píng)論

安庆市| 龙游县| 长顺县| 增城市| 隆子县| 中宁县| 房产| 长春市| 齐河县| 滦南县| 祁连县| 石泉县| 库车县| 洛川县| 灵川县| 苍南县| 博乐市| 琼结县| 松原市| 凉山| 五寨县| 陕西省| 昭觉县| 武功县| 南靖县| 卓尼县| 尤溪县| 廉江市| 明星| 衡山县| 阿拉善盟| 新巴尔虎左旗| 米林县| 长春市| 福鼎市| 固始县| 深泽县| 平阳县| 临泉县| 高要市| 韶关市|