python協程的前世今生的簡單介紹

本文目錄一覽:

python異步協程跟多進程多線程哪個效率高?

線程是操作系統能夠進行運算調度的最小單位。它被包含在進程之中,是進程中的實際運作單位。

一個程序的執行實例就是一個進程。每一個進程提供執行程序所需的所有資源。

PS:上面都是摘抄自網頁鏈接這裡的,具體的可以看看這裡,你的答案在圖片的最後一點。因為線程和進程是不能層面的定義,一個進程可以包括多個線程,所以沒有可比性~

協程與異步IO

協程,又稱微線程,纖程。英文名 Coroutine 。Python對協程的支持是通過 generator 實現的。在generator中,我們不但可以通過for循環來迭代,還可以不斷調用 next()函數 獲取由 yield 語句返回的下一個值。但是Python的yield不但可以返回一個值,它還可以接收調用者發出的參數。yield其實是終端當前的函數,返回給調用方。python3中使用yield來實現range,節省內存,提高性能,懶加載的模式。

asyncio是Python 3.4 版本引入的 標準庫 ,直接內置了對異步IO的支持。

從Python 3.5 開始引入了新的語法 async 和 await ,用來簡化yield的語法:

import asyncio

import threading

async def compute(x, y):

    print(“Compute %s + %s …” % (x, y))

    print(threading.current_thread().name)

    await asyncio.sleep(x + y)

    return x + y

async def print_sum(x, y):

    result = await compute(x, y)

    print(“%s + %s = %s” % (x, y, result))

    print(threading.current_thread().name)

if __name__ == “__main__”:

    loop = asyncio.get_event_loop()

    tasks = [print_sum(1, 2), print_sum(3, 4)]

    loop.run_until_complete(asyncio.wait(tasks))

    loop.close()

線程是內核進行搶佔式的調度的,這樣就確保了每個線程都有執行的機會。而 coroutine 運行在同一個線程中,由語言的運行時中的 EventLoop(事件循環) 來進行調度。和大多數語言一樣,在 Python 中,協程的調度是非搶佔式的,也就是說一個協程必須主動讓出執行機會,其他協程才有機會運行。

讓出執行的關鍵字就是 await。也就是說一個協程如果阻塞了,持續不讓出 CPU,那麼整個線程就卡住了,沒有任何並發。

PS: 作為服務端,event loop最核心的就是IO多路復用技術,所有來自客戶端的請求都由IO多路復用函數來處理;作為客戶端,event loop的核心在於利用Future對象延遲執行,並使用send函數激發協程,掛起,等待服務端處理完成返回後再調用CallBack函數繼續下面的流程

Go語言的協程是 語言本身特性 ,erlang和golang都是採用了CSP(Communicating Sequential Processes)模式(Python中的協程是eventloop模型),但是erlang是基於進程的消息通信,go是基於goroutine和channel的通信。

Python和Go都引入了消息調度系統模型,來避免鎖的影響和進程/線程開銷大的問題。

協程從本質上來說是一種用戶態的線程,不需要系統來執行搶佔式調度,而是在語言層面實現線程的調度 。因為協程 不再使用共享內存/數據 ,而是使用 通信 來共享內存/鎖,因為在一個超級大系統里具有無數的鎖,共享變量等等會使得整個系統變得無比的臃腫,而通過消息機制來交流,可以使得每個並發的單元都成為一個獨立的個體,擁有自己的變量,單元之間變量並不共享,對於單元的輸入輸出只有消息。開發者只需要關心在一個並發單元的輸入與輸出的影響,而不需要再考慮類似於修改共享內存/數據對其它程序的影響。

python為什麼引入協程

python的多線程是偽的,因為python有GIL(全局解釋器鎖,這個你不知道可以自己 百度),同一個cpu只能同時執行一個任務,多線程同一時刻只有拿到GIL的線程在執行。而協程也是並發執行多個任務,但是是在程序員的控制下按序執行,比起線程,協程可控性要強,效率跟線程差不多,所以引入了協程來替代大多數情況下的線程。

python協程(4):asyncio

asyncio是官方提供的協程的類庫,從python3.4開始支持該模塊

async awiat是python3.5中引入的關鍵字,使用async關鍵字可以將一個函數定義為協程函數,使用awiat關鍵字可以在遇到IO的時候掛起當前協程(也就是任務),去執行其他協程。

await + 可等待的對象(協程對象、Future對象、Task對象 – IO等待)

注意:在python3.4中是通過asyncio裝飾器定義協程,在python3.8中已經移除了asyncio裝飾器。

事件循環,可以把他當做是一個while循環,這個while循環在周期性的運行並執行一些協程(任務),在特定條件下終止循環。

loop = asyncio.get_event_loop():生成一個事件循環

loop.run_until_complete(任務):將任務放到事件循環

Tasks用於並發調度協程,通過asyncio.create_task(協程對象)的方式創建Task對象,這樣可以讓協程加入事件循環中等待被調度執行。除了使用 asyncio.create_task() 函數以外,還可以用低層級的 loop.create_task() 或 ensure_future() 函數。不建議手動實例化 Task 對象。

本質上是將協程對象封裝成task對象,並將協程立即加入事件循環,同時追蹤協程的狀態。

注意:asyncio.create_task() 函數在 Python 3.7 中被加入。在 Python 3.7 之前,可以改用 asyncio.ensure_future() 函數。

下面結合async awiat、事件循環和Task看一個示例

示例一:

*注意:python 3.7以後增加了asyncio.run(協程對象),效果等同於loop = asyncio.get_event_loop(),loop.run_until_complete(協程對象) *

示例二:

注意:asyncio.wait 源碼內部會對列表中的每個協程執行ensure_future從而封裝為Task對象,所以在和wait配合使用時task_list的值為[func(),func()] 也是可以的。

示例三:

python協程為什麼不需要枷鎖

Python是一門動態的腳本語言,它有一個鎖叫做全局解釋器鎖,它這個鎖是加在cpython解釋器上的,我們說的Python多線程,再線程切換的時候加了鎖,用了控制同步。所以多線程不是真正意義的並發,而協程是在線程裡面的,線程並沒有鎖,一個線程可以有多個協程,協程又叫微線程,它的切換完全由自己創建,它有幾種實現方式,一種是yield和send,一種是gevent,一種是greenlet,線程的並發不好,協程可以有上萬次並發。回到之前的問題,因為協程在線程內,而線程本身沒有鎖,所以攜程沒有鎖。

簡述python進程,線程和協程的區別及應用場景

協程多與線程進行比較

1) 一個線程可以多個協程,一個進程也可以單獨擁有多個協程,這樣python中則能使用多核CPU。

2) 線程進程都是同步機制,而協程則是異步

3) 協程能保留上一次調用時的狀態,每次過程重入時,就相當於進入上一次調用的狀態

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/207025.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-08 14:19
下一篇 2024-12-08 14:20

相關推薦

  • Python中引入上一級目錄中函數

    Python中經常需要調用其他文件夾中的模塊或函數,其中一個常見的操作是引入上一級目錄中的函數。在此,我們將從多個角度詳細解釋如何在Python中引入上一級目錄的函數。 一、加入環…

    編程 2025-04-29
  • Python列表中負數的個數

    Python列表是一個有序的集合,可以存儲多個不同類型的元素。而負數是指小於0的整數。在Python列表中,我們想要找到負數的個數,可以通過以下幾個方面進行實現。 一、使用循環遍歷…

    編程 2025-04-29
  • Python周杰倫代碼用法介紹

    本文將從多個方面對Python周杰倫代碼進行詳細的闡述。 一、代碼介紹 from urllib.request import urlopen from bs4 import Bea…

    編程 2025-04-29
  • 如何查看Anaconda中Python路徑

    對Anaconda中Python路徑即conda環境的查看進行詳細的闡述。 一、使用命令行查看 1、在Windows系統中,可以使用命令提示符(cmd)或者Anaconda Pro…

    編程 2025-04-29
  • Python計算陽曆日期對應周幾

    本文介紹如何通過Python計算任意陽曆日期對應周幾。 一、獲取日期 獲取日期可以通過Python內置的模塊datetime實現,示例代碼如下: from datetime imp…

    編程 2025-04-29
  • python強行終止程序快捷鍵

    本文將從多個方面對python強行終止程序快捷鍵進行詳細闡述,並提供相應代碼示例。 一、Ctrl+C快捷鍵 Ctrl+C快捷鍵是在終端中經常用來強行終止運行的程序。當你在終端中運行…

    編程 2025-04-29
  • Python字典去重複工具

    使用Python語言編寫字典去重複工具,可幫助用戶快速去重複。 一、字典去重複工具的需求 在使用Python編寫程序時,我們經常需要處理數據文件,其中包含了大量的重複數據。為了方便…

    編程 2025-04-29
  • 蝴蝶優化算法Python版

    蝴蝶優化算法是一種基於仿生學的優化算法,模仿自然界中的蝴蝶進行搜索。它可以應用於多個領域的優化問題,包括數學優化、工程問題、機器學習等。本文將從多個方面對蝴蝶優化算法Python版…

    編程 2025-04-29
  • Python程序需要編譯才能執行

    Python 被廣泛應用於數據分析、人工智能、科學計算等領域,它的靈活性和簡單易學的性質使得越來越多的人喜歡使用 Python 進行編程。然而,在 Python 中程序執行的方式不…

    編程 2025-04-29
  • Python清華鏡像下載

    Python清華鏡像是一個高質量的Python開發資源鏡像站,提供了Python及其相關的開發工具、框架和文檔的下載服務。本文將從以下幾個方面對Python清華鏡像下載進行詳細的闡…

    編程 2025-04-29

發表回復

登錄後才能評論