系統學習Python——并發模型和異步編程:基礎知識

分類目錄:《系統學習Python》總目錄


并行是并發的一種特殊情況。**所有并行系統都是并發的,但不是所有并發系統都是并行的。**在21世紀初,我們可以使用單核設備在GNU Linux上同時處理100個進程。一臺擁有4個CPU核的現代筆記本計算機,在正常情況下,任何時間段內運行的進程數隨隨便便都會超過200個。如果并行執行200個任務,則需要200個核。因此,多數計算實際是并發的,而不是并行的。操作系統管理著數百個進程,確保每個進程都有機會取得進展,即使CPU本身同時做的事情不能超過4件。

《系統學習Python——并發模型和異步編程》系列文章假定我們事先不具備并發或并行編程知識。我們會簡要介紹相關概念之后,將通過簡單的示例學習和比較Python為并發編程提供的3個核心包:threadingmultiprocessingasyncio。我們還會講解增強Python應用性能和伸縮性的第三方工具、庫、應用服務器和分布式任務隊列。同時,我們也會講解Python的3種并發方式:線程、進程和原生協程。

導致并發編程困難的因素很多,但我們會講到啟動線程或進程以及如何跟蹤線程或進程。調用一個函數,發出調用的代碼開始阻塞,直到函數返回。因此,我們知道函數什么時候執行完畢,而且能輕松地得到函數的返回值。如果函數可能拋出異常,則把函數調用放在try/except塊中,捕獲錯誤。這些熟悉的概念在我們啟動線程或進程后都不可用了。同時,我們無法輕松地得知操作何時結束,若想獲取結果或捕獲錯誤,則需要設置某種通信信道,例如消息隊列。此外,啟動線程或進程有一定消耗,僅僅為了計算一個結果就退出,肯定得不償失。通常,更好的選擇是讓各個線程或進程進入一個職程(Worker),循環等待要處理的輸入,以此分攤啟動成本。但是,這又進一步增加了通信難度,還會引起更多問題。如果不需要職程了,那么如何退出呢?怎樣退出才能做到不中斷作業,避免留下未處理完畢的數據和未釋放的資源(例如打開的文件)呢?同樣,解決這些問題通常涉及消息和隊列。協程的啟動成本很低。使用await關鍵字啟動的協程,返回值容易獲取,可以安全取消,捕獲異常的位置也明確。但是,協程通常由異步框架啟動,因此監控難度與線程或進程相當。

最后,我們還會說明Python協程和線程不適合CPU密集型任務。鑒于此,并發編程需要學習新的概念和編程模式。首先,我們要對核心概念確立統一認識。

術語定義

  • 并發:處理多個待定任務,一次處理一個或并行處理多個(如果條件允許)?,直到所有任務最終都成功或失敗。對于單核CPU,如果操作系統的調度程序支持交叉執行待定任務,也能實現并發。并發也叫多任務處理(Multitasking)。
  • 并行:同時執行多個計算任務的能力。需要一個多核CPU、多個CPU、一個GPU或一個集群中的多臺計算機。
  • 執行單元:并發執行代碼的對象的統稱,每個對象的狀態和調用棧是獨立的。Python原生支持3種執行單元:進程、線程和協程。
  • 進程:計算機程序運行時的一個實例,消耗內存和部分CPU時間。現代桌面操作系統通常同時管理數百個進程,每個進程都隔離在自己的私有內存空間中。進程通過管道、套接字或內存映射文件進行通信—這些方式都只能攜帶原始字節。Python對象必須序列化(轉換)為原始字節才能從一個進程傳遞到另一個進程。這個過程耗費資源,而且不是所有Python對象都可以序列化。**進程可以派生子進程,子進程彼此之間以及與父進程之間是隔離的。**進程支持搶占式多任務處理機制:操作系統調度程序定期搶占(掛起)運行中的進程,讓其他進程運行。這意味著凍結的進程理論上不會凍結整個系統。
  • 線程:單個進程中的執行單元。**一個進程啟動后,只使用一個線程,即主線程。通過調用操作系統API,進程可以創建更多線程,執行并發操作。**一個進程內的線程共享相同的內存空間(存儲活動的Python對象)?。因此,線程之間可以輕松地共享數據,但是如果多個線程同時更新同一個對象,則可能導致數據損壞。與進程一樣,線程在操作系統調度程序的監督下也可以實現搶占式多任務處理。對于同一份作業,線程消耗的資源比進程少。
  • 協程:可以掛起自身并在以后恢復的函數。在Python中,經典協程由生成器函數構建,原生協程使用async def定義。我們在已經《系統學習Python》之前的文章中介紹過經典協程,原生協程的用法將在《系統學習Python——并發模型和異步編程》系列文章中討論。Python協程通常在事件循環(也在同一個線程中)的監督下在單個線程中運行。asyncioCurioTrio等異步編程框架為基于協程的非阻塞I/O提供了事件循環和支持庫。協程支持協作式多任務處理:一個協程必須使用yieldawait關鍵字顯式放棄控制權,另一個協程才可以并發(而非并行)開展工作。這意味著,協程中只要有導致阻塞的代碼,事件循環和其他所有協程的執行就都會受到阻塞,這一點與進程和線程的搶占式多任務處理形成鮮明對比。另外,對于同一份作業,協程消耗的資源比線程或進程少。
  • 隊列:一種數據結構,可以放入和取出項,順序通常是先入先出(FIFO)。獨立的執行單元可以通過隊列交換應用數據和控制消息,例如錯誤代碼和終止信號。隊列的實現因底層并發模型而異:Python標準庫中的queue包提供的隊列類支持線程,multiprocessingasyncio包則實現了其他隊列類。queueasyncio包中還有非先入先出隊列:LifoQueuePriorityQueue
  • 鎖:一種供執行單元用來同步操作和避免數據損壞的對象。更新共享數據結構時,當前代碼應持有相關的鎖,并告訴程序的其他部分等到鎖被釋放后再訪問這個數據結構。最簡單的鎖是互斥鎖。鎖的實現取決于底層并發模型。
  • 爭用:對有限資源的爭奪。當多個執行單元嘗試訪問共享資源(例如鎖或存儲器)時,就會發生資源爭用。當計算密集型進程或線程必須等待操作系統調度程序為其分配CPU時間時,還會發生CPU爭用。

參考文獻:
[1] Mark Lutz. Python學習手冊[M]. 機械工業出版社, 2018.
[2] 盧西亞諾·拉馬略.流暢的Python 第2版(全2冊) 編程語言[M].人民郵電出版社,2023.

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/87918.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/87918.shtml
英文地址,請注明出處:http://en.pswp.cn/web/87918.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

睿爾曼系列機器人——以創新驅動未來,重塑智能協作新生態(下)

在智能制造與人工智能深度融合的當下,機器人技術正經歷從 “功能替代” 到 “價值共創” 的深刻躍遷。睿爾曼,作為全球超輕量仿人機械臂領域的先行者,始終秉持 “讓機器人觸手可及” 的使命,憑借底層技術的突破性進展,…

表征工程(Representation Engineering, RepE)

表征工程(Representation Engineering, RepE) 近年來,表征工程(Representation Engineering, RepE)在提升AI系統透明度和可控性方面取得了顯著進展。 一、大模型可解釋性與可控性的突破 核心論文:《Representation Engineering: A Top-Down Approach to AI Transparen…

國產ARM+FPGA工業開發平臺——GM-3568JHF

一、引言 隨著物聯網和國產替代需求的快速發展,嵌入式系統面臨計算性能與硬件靈活性的雙重挑戰。GM-3568JHF開發板基于國產“ARMFPGA”異構架構,結合瑞芯微RK3568J處理器與紫光同創Logos-2 FPGA芯片,支持國產自主操作系統,滿足通…

RISCV Linux 虛擬內存精講系列一 Sv39

筆者認為,Linux 操作系統(Operating System)最核心的機制是虛擬內存(Virtual Memory)。因為,操作系統主要作用是將硬件環境抽象起來,給在其中運行的應用(Applications)提…

【apply from: “$flutterRoot/packages/flutter_tools/gradle/flutter.gradle“作用】

這行代碼的作用是將 Flutter 的 Gradle 構建腳本集成到 Android 項目中,具體細節如下:作用解析:引入 Flutter 構建邏輯 flutter.gradle 是 Flutter SDK 的核心構建腳本,它負責: 編譯 Dart 代碼為原生二進制文件&#x…

深入理解JavaScript設計模式之命令模式

深入理解JavaScript設計模式之命令模式 文章目錄深入理解JavaScript設計模式之命令模式定義簡單命令模式組合命令模式使用命令模式實現文本編輯器目標關鍵類說明實現的效果交互邏輯流程所有代碼:總結定義 命令模式也是設計模式種相對于變焦簡單容易理解的一種設計模…

CSS 網頁布局:從基礎到進階

CSS 網頁布局:從基礎到進階 引言 隨著互聯網的飛速發展,網頁設計已經成為了一個不可或缺的領域。CSS(層疊樣式表)作為網頁設計中的關鍵工具,用于控制網頁元素的樣式和布局。本文將為您全面解析CSS網頁布局,…

【人工智能】大語言模型(LLM) NLP

大語言模型(LLM)& NLP1.大語言模型(LLM)1.1 一句話解釋1.2 更形象的比喻1.3 為什么叫 “大” 模型1.4 它能做什么1.5 現實中的例子2.對比 NLP2.1 用 “汽車進化” 比喻 NLP → LLM2.2 為什么說 LLM 屬于 NLP2.3 LLM 的 “革命…

Unity HDRP + Azure IoT 的 Python 后端實現與集成方案

Unity HDRP Azure IoT 的 Python 后端實現與集成方案 雖然Unity HDRP本身使用C#開發,但我們可以構建Python后端服務支持物聯網系統,并與Unity引擎深度集成。以下是完整的實現方案: 系統架構 #mermaid-svg-qCDb0g9Ik287Cg8X {font-family:&qu…

小黑黑日常積累大模型prompt句式2:【以段落的形式輸出,不分點列舉】【如果沒有相關內容則不輸出】【可讀性強】【輸出格式規范】

以段落的形式輸出,不分點列舉 每個標題下直接接續段落內容,不編號、不分點。......標題下直接接續段落內容,不繼續進行分點列舉。如果沒有相關內容則不輸出 若某一部分無法從原文中提取有效信息,則跳過該部分內容,不做…

React Native 基礎組件詳解<一>

一、Text組件 1)numberOfLines:顯示行數 2)ellipsizeMode:超出隱藏的位置 clip->裁掉 head/middle/ tail->點的位置 3)selectable: 是否可以選中 4)selectionColor:選中后的顏色 5&#…

異步編程(Promise/Generator/async)

1、Promise 2、Generator 3、async/await

【Note】《Kafka: The Definitive Guide》 第8章: Cross-Cluster Data Mirroring

《Kafka: The Definitive Guide》 第8章: Cross-Cluster Data Mirroring 一、跨集群鏡像的場景與價值 多區域低延遲訪問 將業務數據從主集群實時復制到多個地理區域的集群,縮短消費者跨區讀取延遲。 災備切換 當主集群出現故障時,可快速將消…

「Windows/Mac OS」AIGC圖片生成視頻 ,webui + stable-diffusion環境部署教程

stable-diffusion webui 環境搭建目錄 一、Windows 環境部署 stable-diffusion-webui1、準備條件2、安裝Python 3.10.X(**較新版本的 Python 不支持 torch**)3、安裝Git 教程4、使用Git 下載 stable-diffusion-webui 存儲庫,4.1、顯示報錯 5…

【深度學習】 深度學習訓練配置參數詳解

深度學習訓練配置參數詳解 1. 啟動初始化參數說明CUDA_VISIBLE_DEVICES指定使用的GPU設備編號("0"表示單卡)seed隨機種子(1777777),保證實驗可復現性cuda是否啟用GPU加速(True)benchm…

期望,積分,均值,求和的關系

1. 回顧期望的定義 對于連續性隨機變量 X X X,期望為: E X ~ f ( x ) [ X ] ∫ Ω x f ( x ) d x E_{X\sim f(x)}[X] \int_{\Omega}xf(x)dx EX~f(x)?[X]∫Ω?xf(x)dx 其中 f ( x ) f(x) f(x)為概率密度函數, Ω \Omega Ω為概率密度函…

1.如何對多個控件進行高效的綁定 C#例子 WPF例子

使用ObservableCollection高效為多個控件綁定數據在WPF開發中,數據綁定是一個非常重要的功能,它允許我們將UI控件與數據源進行綁定,從而實現數據的自動更新。當需要為多個控件綁定數據時,使用ObservableCollection可以大大提高開發…

JSONLines和JSON數據格式使用教程

文章目錄 一、核心區別二、JSONLines 的優勢三、Python 中使用 JSONLines1. 寫入 JSONLines 文件2. 讀取 JSONLines 文件3. 處理大文件示例四、常見工具支持1. 命令行工具2. 編程語言庫五、適用場景選擇六、注意事項總結JSONLines(簡稱 jsonl 或 jl)和傳統 JSON 都是用于存儲…

鏈表算法之【反轉鏈表】

目錄 LeetCode-206題 LeetCode-206題 給定一個單鏈表的頭節點,請反轉鏈表,并返回反轉后的鏈表 class Solution {public ListNode reverseList(ListNode head) {// checkif (head null || head.next null)return head;// 雙指針ListNode p1 head;Li…

回溯題解——子集【LeetCode】輸入的視角(選或不選)

78. 子集 ? 一、算法邏輯講解(逐步思路) 邏輯講解: dfs(i):表示從下標 i 開始,做“選 or 不選”的子集構造。 終止條件 if i n: 到達數組末尾,表示一種完整子集構造完成。 把當前構造路徑…