Day05: Python 中的并發和并行(1)

理解 Python 中的線程和進程

理解線程和進程是實現在 Python 中并發和并行的基礎。這種知識使你能夠編寫能夠看似同時執行多個任務的程序,從而提高性能和響應能力。本課程將深入探討線程和進程的核心概念、它們的區別,以及它們如何為更高級的并發技術奠定基礎。

線程:輕量級并發

線程是同一進程內的獨立執行路徑。它們共享相同的內存空間,這使得它們能夠輕松訪問和修改相同的數據。這種共享內存模型使得線程間的通信相對簡單,但也引入了競態條件和其它同步問題的風險。

線程的概念

線程可以被視為一個輕量級子進程。操作系統管理線程,允許它們并發運行。當一個線程正在等待資源或執行阻塞操作(如 I/O)時,操作系統可以切換到另一個線程,使 CPU 保持忙碌。

示例:?想象一個文字處理器。一個線程可能處理用戶輸入,另一個線程可能在后臺執行拼寫檢查,還有一個線程可能定期自動保存文檔。所有這些線程都在同一個文字處理器應用程序(進程)中運行。

線程的優點

  • 輕量級:?創建和銷毀線程通常比創建和銷毀進程更快,并且消耗更少的資源。
  • 共享內存:?同一進程內的線程可以輕松共享數據,簡化了通信和數據交換。
  • 響應性:?多線程可以通過允許應用程序在某個線程被阻塞時繼續執行其他任務來提高其響應性。

線程的缺點

  • 全局解釋器鎖 (GIL):?在 CPython 中,標準的 Python 解釋器,GIL 允許在任何給定時間只有一個線程持有對 Python 解釋器的控制權。這限制了多線程 Python 程序中 CPU 密集型任務的真實并行性。然而,I/O 密集型任務仍然可以從多線程中受益,因為當線程等待 I/O 時 GIL 會被釋放。
  • 同步問題:?由于線程共享內存,如果不同步,它們可能會相互干擾。這可能導致競態條件、死鎖和其他并發問題。
  • 調試復雜性:?由于線程執行的不可確定性,調試多線程程序可能比調試單線程程序更具挑戰性。

線程的實際示例

  1. Web Server:?Web 服務器可以使用多個線程來并發處理傳入的客戶端請求。每個線程可以獨立地處理一個請求,使服務器能夠同時服務多個客戶端。
  2. 圖形界面應用程序:?圖形界面應用程序通常使用線程來保持用戶界面的響應性。例如,一個單獨的線程可以處理長時間運行的任務,如下載文件,而不會阻塞主 UI 線程。
  3. 數據處理:?數據處理應用程序可以使用線程來并發處理不同的數據塊,從而加快整體處理時間。

代碼示例:基本線程

import threading
import timedef task(name):print(f"Thread {name}: Starting")time.sleep(2)  # Simulate a time-consuming taskprint(f"Thread {name}: Finishing")# 創建并啟動多個線程
threads = []
for i in range(3):t = threading.Thread(target=task, args=(f"Thread-{i+1}",))threads.append(t)t.start()# 等待所有線程完成
for t in threads:t.join()print("所有線程完成")

解釋:

  • threading?模塊被導入以處理線程。
  • task?函數使用?time.sleep()?模擬耗時操作。
  • 創建了三個線程,每個線程以不同的名稱運行?task?函數。
  • t.start()?啟動每個線程。
  • t.join()?會等待每個線程完成后再繼續主程序。

進程:獨立執行

進程是并發運行的獨立程序。每個進程都有自己獨立的內存空間,這意味著進程不能直接共享數據。進程之間的通信需要進程間通信(IPC)機制,例如管道、套接字或共享內存。

進程的概念

進程是一個正在執行的程序的實例。操作系統為每個進程分配資源,例如內存和 CPU 時間。進程之間是相互隔離的,這意味著一個進程不能直接訪問另一個進程的內存或資源。

示例:?考慮運行兩個文本編輯器實例。每個實例是一個獨立進程,擁有自己的內存空間和資源。如果一個實例崩潰,它不會影響另一個實例。

進程的優勢

  • 真正的并行性:?進程可以在多核處理器上實現真正的并行性,因為每個進程都有自己的解釋器和內存空間,從而繞過了 GIL 的限制。
  • 隔離:?進程彼此隔離,這意味著一個進程的崩潰不會影響其他進程。
  • 安全:?進程隔離通過防止一個進程訪問或修改其他進程的數據來增強安全性。

進程的缺點

  • 開銷:?創建和銷毀進程通常比創建和銷毀線程更耗費資源。
  • 進程間通信(IPC):?進程間的通信需要 IPC 機制,這比線程間的共享內存通信可能更復雜且更慢。
  • 內存占用:?每個進程都有自己的內存空間,與多線程應用程序相比,這可能導致更大的內存占用。

進程的實際案例

  1. 視頻編碼:?一個視頻編碼應用程序可以使用多個進程同時編碼視頻的不同片段,顯著減少編碼時間。
  2. 科學計算:?科學計算應用通常使用多個進程來并行執行復雜的計算,利用多核處理器的強大功能。
  3. 分布式系統:?分布式系統使用運行在不同機器上的多個進程來并行執行任務,并提供高可用性和可擴展性。

代碼示例:基本多進程

import multiprocessing
import timedef task(name):print(f"Process {name}: Starting")time.sleep(2)  # 模擬耗時的任務print(f"Process {name}: Finishing")if __name__ == "__main__":# 創建并啟動多個進程processes = []for i in range(3):p = multiprocessing.Process(target=task, args=(f"Process-{i+1}",))processes.append(p)p.start()# 等待所有進程完成for p in processes:p.join()print("所有進程完成")

解釋:

  • multiprocessing?模塊被導入以處理進程。
  • task?函數使用?time.sleep()?模擬耗時操作。
  • 創建了三個進程,每個進程都運行不同的?task?函數。
  • p.start()?啟動每個進程。
  • p.join()?會等待每個進程完成后再繼續主程序。
  • if __name__ == "__main__":?代碼塊是必要的,以防止在某些操作系統上子進程遞歸地創建新進程。

線程與進程:主要區別

特性線程進程
內存空間共享獨立
資源消耗輕量級重量級
并行性受 GIL(在 CPython 中)限制多核 CPU 上的真正并行
隔離
通信共享內存,更容易實現IPC 機制,更復雜
上下文切換更快更慢
碰撞影響一個線程崩潰會影響整個進程一個進程崩潰不會影響其他進程

在線程和進程之間進行選擇

  • I/O 密集型任務:?對于 I/O 密集型任務,線程通常是較好的選擇,因為程序大部分時間都在等待 I/O 操作完成。當線程等待 I/O 時,GIL 會被釋放,允許其他線程運行。
  • CPU 密集型任務:?對于 CPU 密集型任務,進程通常是更好的選擇,因為程序大部分時間都在進行計算。進程可以在多核處理器上實現真正的并行性,繞過 GIL 的限制。
  • 隔離:?如果隔離是一個關鍵要求,進程是首選的選擇。
  • 復雜性:?線程通常比進程更容易實現和管理,尤其是在共享數據方面。

實際應用

考慮一個大規模數據處理流程。該流程包含多個階段,如數據采集、數據清洗、數據轉換和數據分析。線程和進程都可以用來并行化該流程,但選擇取決于所涉及任務的性質。

  • 數據采集:?如果數據采集涉及從多個網絡源讀取數據(I/O 密集型),可以使用線程來同時處理多個連接。
  • 數據清洗和轉換:?如果數據清洗和轉換涉及 CPU 密集型操作,例如復雜的計算或字符串操作,可以使用進程來利用多個核心,實現真正的并行處理。
  • 數據分析:?根據分析的復雜性,可以使用線程或進程。對于簡單的分析任務,線程可能就足夠了。對于更復雜的數據分析任務,可能需要使用進程來達到最佳性能。

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

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

相關文章

Spring Boot 集成 MinIO 實現分布式文件存儲與管理

Spring Boot 集成 MinIO 實現分布式文件存儲與管理 一、MinIO 簡介 MinIO 是一個高性能的分布式對象存儲服務器,兼容 Amazon S3 API。它具有以下特點: 輕量級且易于部署高性能(讀寫速度可達每秒數GB)支持數據加密和訪問控制提供…

從小白入門,基于Cursor開發一個前端小程序之Cursor 編程實踐與案例分析

Cursor 編程實踐與案例分析 Cursor 編程實踐與案例分析 1. 什么是 Cursor? Cursor 是一款面向開發者的 AI 編程助手,集成于本地 IDE,支持自然語言與代碼的無縫協作。它不僅能自動補全、重構、查找代碼,還能理解業務上下文&#…

一、如何用MATLAB畫一個三角形 代碼

一、如何用MATLAB畫一個三角形 代碼在MATLAB中繪制三角形可以通過指定三個頂點的坐標并使用 fill 或 patch 函數實現。以下是詳細代碼示例:方法1:使用 fill 函數(簡單填充)% 定義三角形的三個頂點坐標 (x, y) x [0, 1, 0.5]; % …

Postman自動化測試提取相應body體中的參數

文章目錄Postman自動化測試提取相應body體中的參數1. 示例響應 Body 參數2. 提取響應 Body 參數Postman自動化測試提取相應body體中的參數 上一篇的文中介紹了使用postman自動化測試時從響應的header中提取token參數,很多同學私信問如何從響應體body中提取參數。 有…

vue-39(為復雜 Vue 組件編寫單元測試)

實際練習:為復雜 Vue 組件編寫單元測試 單元測試對于確保復雜 Vue 組件的可靠性和可維護性至關重要。通過隔離和測試代碼的各個單元,您可以在開發過程的早期發現并修復錯誤,從而構建更健壯和可預測的應用程序。本課程重點介紹為復雜 Vue 組件編寫單元測試的實用方面,建立在…

c語言中的函數IV

函數的先后關系 直接把函數放在程序上方是可以的 在實際開發中,我們更希望把main函數放在前面 這樣子直接把自己定義的函數放在main函數下方,編譯會出現warning和error正確的解決方案是:把函數的頭放到main函數上方,這樣就能正常…

大模型Decoder-Only深入解析

Decoder-Only整體結構 我們以模型Llama-3.1-8B-Instruct為例,打印其結構如下(后面會慢慢解析每一部分,莫慌): LlamaForCausalLM((model): LlamaModel((embed_tokens): VocabParallelEmbedding(num_embeddings128256,…

web網頁,在線%電商,茶葉,商城,網上商城系統%分析系統demo,于vscode,vue,java,jdk,springboot,mysql數據庫

經驗心得 這也是幫之前一客戶加了幾個功能,需要掌握crud,前后端開發,前后端怎么對接,前后端通訊是以那種格式,把這些掌握后咱們就可以進行網站開發了。后端記好一定要分層開發,不要像老早一起所有代碼寫到一…

MybatisPlus-05.核心功能-條件構造器

一.條件構造器 我們前面使用的MP功能主要是根據id進行操作的,并未涉及到復雜查詢。而根據id所進行的增刪改查操作在MP中都有直接的封裝。但是遇到復雜的查詢條件時,如何使用MP進行操作是我們要考慮的問題。因此MP為我們提供了條件構造器。 在BaseMapper…

ES6從入門到精通:常用知識點

變量聲明ES6引入了let和const替代var。let用于聲明可變的塊級作用域變量,const用于聲明不可變的常量。塊級作用域有效避免了變量提升和污染全局的問題。let name Alice; const PI 3.1415;箭頭函數箭頭函數簡化了函數寫法,且自動綁定當前上下文的this值…

51單片機教程(十一)- 單片機定時器

11、單片機定時器 項目目標 通過定時器/計數器實現流水燈控制。知識要點 定時器的結構。TMOD和TCON;定時/計數器工作方式;定時/計數器編程步驟;1、項目分析 前面的流水燈的時間控制通過空循環語句來實現,定時不是很精確。本章通過用定時器來控制流水燈任務可以實現精確的時…

基于opencv的疲勞駕駛監測系統

博主介紹:java高級開發,從事互聯網行業多年,熟悉各種主流語言,精通java、python、php、爬蟲、web開發,已經做了多年的畢業設計程序開發,開發過上千套畢業設計程序,沒有什么華麗的語言&#xff0…

Vue 2 和 Vue 3 區別

1. 響應式系統原理 Vue 2:利用Object.defineProperty()實現屬性攔截。存在局限性,無法自動監測對象屬性增減,需用Vue.set/delete;數組變異方法要重寫;深層對象遞歸轉換性能差。Vue 3:采用 ES6 Proxy代理對…

mv重命名報錯:-bash:syntax error near unexpected token ‘(‘

文章目錄 一、報錯背景二、解決方法2.1、方法一:文件名加引號2.2、方法二:特殊字符前加\進行轉義 一、報錯背景 在linux上對一文件執行重命名時報錯。原因是該文件名包含空格與括號。 文件名如下: aa (1).txt執行命令及報錯如下…

AWS 開源 Strands Agents SDK,簡化 AI 代理開發流程

最近,亞馬遜網絡服務(AWS)宣布推出 Strands Agents(https://github.com/strands-agents/sdk-python),這一開源軟件開發工具包(SDK)采用模型驅動的方法,助力開發者僅用數行代碼即可構建并運行人工…

利用 AI 打造的開發者工具集合

如圖. 我利用 AI 開發了這個網站花了半個小時. 目前就上了 四個 我想到的工具。 大家可以自行體驗下:https://xiaojinzi123.github.io 本文并不是宣傳什么產品. 只是感概 Ai 真的改變我的工作方式啊. 雖然現在 AI 對于一些已有的項目進行更改代碼. 由于不了解業務,…

[自然語言處理]計算語言的熵

一、要求利用給定的中英文語料,分別計算英語字母、英語單詞、漢字、漢語詞的熵,并和已公開結果比較,思考漢語的熵對漢語編碼和處理的影響。二、實驗內容2.1 統計英文語料的熵1.代碼(1)計算英文字母的熵import math #計算每個英文字母的熵 def…

如何處理“協議異常”錯誤

在Java中,“協議異常”通常是指在網絡通信或者處理特定協議相關操作時出現的異常。以下是一些處理“協議異常”錯誤的方法:一、理解協議異常的類型和原因HTTP協議異常原因:在進行HTTP通信時,可能會因為請求格式錯誤、響應狀態碼異…

Spark 4.0的VariantType 類型以及內部存儲

背景 本文基于Spark 4.0 總結 Spark中的 VariantType 類型,用盡量少的字節來存儲Json的格式化數據 分析 這里主要介紹 Variant 的存儲,我們從VariantBuilder.buildJson方法(把對應的json數據存儲為VariantType類型)開始: public static Variant parseJson(JsonParser …

跨越十年的C++演進:C++20新特性全解析

跨越十年的C演進系列,分為5篇,本文為第四篇,后續會持續更新C23~ 前3篇如下: 跨越十年的C演進:C11新特性全解析 跨越十年的C演進:C14新特性全解析 跨越十年的C演進:C17新特性全解析 C20標準…