Python并發模型:多線程與多進程的優劣對比與實戰應用

在這里插入圖片描述

文章目錄

    • 多線程基礎概念
    • 多進程基礎概念
    • 多線程的優劣勢
    • 多進程的優劣勢
    • 實戰應用:網絡爬蟲
    • 實戰應用:圖像處理

Python作為一門功能強大的編程語言,提供了多種并發模型,使得我們能夠在同一時間執行多個任務,從而提高程序的執行效率。

在眾多并發模型中,多線程和多進程是最常用的兩種。它們各自有著不同的優劣勢,并適用于不同的場景。

多線程是一種輕量級的并發模型,適用于I/O密集型任務,如文件讀寫、網絡請求等。

在多線程中,所有線程共享同一進程的內存空間,這使得線程之間的通信和數據共享變得非常高效,由于Python的全局解釋鎖(GIL),多線程在處理CPU密集型任務時并不能充分利用多核CPU的優勢。

相對而言,多進程是更為獨立的并發模型,每個進程擁有獨立的內存空間,因此非常適合CPU密集型任務,如復雜計算、圖像處理等。

由于每個進程運行在獨立的Python解釋器中,多進程可以繞過GIL限制,充分利用多核CPU的性能。不過,由于進程之間的通信需要通過進程間通信(IPC)機制實現,因此數據共享的效率不如多線程。

多線程基礎概念

多線程是一種并發執行模型,允許一個程序在不同的線程中同時運行多個操作。這種模型的一個顯著特點是,所有線程共享同一進程的內存空間。

這種共享內存的特性使得線程之間的數據交換變得非常方便,因為它們可以直接訪問和操作共享的數據,而無需像多進程那樣通過復雜的進程間通信(IPC)機制。

多線程示例

import threadingdef print_numbers():for i in range(5):print(f"Number: {i}")thread = threading.Thread(target=print_numbers)
thread.start()
thread.join()

在這段代碼中,我們創建了一個新的線程來執行print_numbers函數。線程啟動后,它會輸出數字0到4。

當調用thread.join()時,主線程會等待該線程執行完成后再繼續運行。這種機制確保了多線程程序的順序性和可控性。

然而,線程共享內存也帶來了線程安全問題。

在多線程環境中,多個線程可能會同時訪問和修改共享數據,這可能導致數據不一致或競爭條件。

為了避免這些問題,我們需要使用線程同步機制,如鎖(Lock)、條件變量(Condition)、信號量(Semaphore)等,來確保線程間的數據訪問是安全的。

例如,可以使用鎖來保護共享數據的訪問:

import threadinglock = threading.Lock()def thread_safe_function():with lock:# 訪問和修改共享數據pass

通過合理使用這些同步機制,我們可以確保多線程程序的正確性和穩定性。

多線程非常適合I/O密集型任務,如網絡請求、文件讀寫等,在這些場景下,它可以顯著提升程序的響應速度和效率。

多進程基礎概念

多進程是一種并發模型,它為每個進程分配獨立的內存空間。

這意味著進程之間的數據交換需要通過進程間通信(IPC)機制來實現,如管道(Pipe)、隊列(Queue)和共享內存等。

多進程適用于CPU密集型任務,因為每個進程可以獨立運行在不同的CPU核心上,從而充分利用多核CPU的計算能力。

多進程示例:

from multiprocessing import Processdef print_numbers():for i in range(5):print(f"Number: {i}")process = Process(target=print_numbers)
process.start()
process.join()

這段代碼與多線程示例類似,但我們使用的是multiprocessing模塊。

每個進程獨立運行,互不干擾,這使得多進程模型在處理CPU密集型任務時具有很大優勢,因為它可以繞過Python的全局解釋鎖(GIL),實現真正的并行執行。

由于每個進程都有獨立的內存空間,多進程模型天然地避免了線程安全問題,不需要擔心多個進程同時訪問和修改同一塊內存。

這種獨立性也帶來了更多的內存開銷,因為每個進程都需要維護自己的內存空間。

在需要進行進程間通信時,可以使用multiprocessing模塊提供的IPC機制。例如,使用隊列來交換數據:

from multiprocessing import Process, Queuedef worker(q):q.put('Data from process')queue = Queue()
process = Process(target=worker, args=(queue,))
process.start()
print(queue.get())
process.join()

通過合理選擇多進程模型,我們可以在處理需要大量計算的任務時顯著提高程序的性能。

雖然多進程會引入額外的內存和進程管理開銷,但在合適的場景下,它的優勢是顯而易見的。

多進程是一種強大且靈活的并發模型,能夠幫助我們在開發高性能應用程序時充分利用現代硬件的多核能力。

多線程的優劣勢

優點

  • 線程之間通信簡單,數據共享方便。
  • 適合I/O密集型任務,如網絡請求、文件讀寫。

缺點

  • 由于Python的GIL(全局解釋器鎖),多線程在CPU密集型任務中并不能提升性能。
  • 需要注意線程安全問題,可能需要使用鎖等機制。

多進程的優劣勢

優點

  • 各個進程獨立運行,適合CPU密集型任務。
  • 不受GIL限制,可以充分利用多核CPU。

缺點

  • 進程間通信復雜,數據共享不如線程方便。
  • 進程啟動和切換的開銷較大。

實戰應用:網絡爬蟲

在編寫網絡爬蟲時,使用多線程可以顯著加速I/O操作,尤其是在處理多個網頁請求時,多線程允許我們同時發起多個網絡請求,從而提高爬蟲的效率和數據抓取速度。

多線程爬蟲示例:

import threading
import requestsurls = ['http://example.com', 'http://example.org']def fetch_url(url):response = requests.get(url)print(f"{url}: {response.status_code}")threads = [threading.Thread(target=fetch_url, args=(url,)) for url in urls]
for thread in threads:thread.start()
for thread in threads:thread.join()

每個線程獨立工作,互不干擾,這種并發請求的方式可以大大提升爬蟲的效率,因為網絡I/O操作通常比CPU操作耗時,而多線程正好可以利用這個特點,在等待網絡響應的同時處理其他請求。

使用多線程抓取網頁時,我們需要謹慎處理。要注意遵守網站的robots.txt文件中的規則,確保爬蟲行為在網站允許的范圍內。

應該設置合理的請求頻率,以避免給目標服務器帶來過大的負擔,導致服務器過載甚至被封禁IP。

可以通過引入請求延遲或使用線程池來控制請求的頻率和并發數量。

還需注意處理網絡請求中的異常情況,如超時、重定向和錯誤響應等,以確保爬蟲的健壯性和穩定性。

通過合理運用多線程技術,我們可以開發出高效、可靠的網絡爬蟲,快速獲取所需的數據,同時也不忘遵循網絡爬蟲的道德和法律規范。

實戰應用:圖像處理

在進行大量圖像處理任務時,使用多進程可以有效地利用CPU資源,提升處理效率。

多進程允許我們在多個CPU核心上同時執行任務,這對于圖像處理這種CPU密集型操作尤為適用。

使用多進程進行圖像濾鏡處理的示例:

from multiprocessing import Pool
from PIL import Image, ImageFilterdef process_image(image_path):with Image.open(image_path) as img:img = img.filter(ImageFilter.BLUR)img.save(f"processed_{image_path}")image_paths = ['image1.jpg', 'image2.jpg']
with Pool(processes=2) as pool:pool.map(process_image, image_paths)

在這個例子中,我們使用multiprocessing.Pool來管理多個進程,每個進程獨立處理一張圖片的濾鏡操作。

通過將任務分配給多個進程,我們能夠同時處理多張圖片,從而充分利用多核CPU的并行計算能力。

這種并行處理方式可以顯著縮短圖像處理的時間,特別是在需要處理大量圖片或應用復雜濾鏡時。

Pool對象提供了一種簡便的方法來并行化任務,我們可以指定進程數來控制并行度。

在此例中,設置了兩個進程來處理兩張圖片。pool.map()方法將任務分發給進程池中的每個進程,確保每個圖像處理任務獨立運行,互不干擾。

使用多進程進行圖像處理時,還需注意內存占用和進程間通信開銷。

雖然多進程能夠繞過Python的全局解釋鎖(GIL),實現真正的并行計算,但每個進程都有獨立的內存空間,這可能會增加內存消耗,在處理大批量圖像時,合理配置進程數和內存資源顯得尤為重要。

通過合理運用多進程技術,我們可以大幅提高圖像處理任務的執行效率,快速完成對大量圖片的處理,同時也能確保處理結果的準確性和一致性。

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

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

相關文章

Spring Boot 整合 Nacos 實戰教程:服務注冊發現與配置中心詳解

Spring Boot 整合 Nacos 教程(3000字) 一、Nacos 簡介 Nacos 是阿里巴巴開源的一個動態服務發現、配置管理和服務管理平臺,致力于幫助開發者更輕松地構建云原生應用。它支持多種注冊中心協議(如 Dubbo、Spring Cloud、Kubernete…

VMware 虛擬機裝 Linux Centos 7.9 保姆級教程(附資源包)

安裝 VMware 17.5.1 centos 7.9 ? 1、下載資源包(虛擬機鏡像) VMware-17.5.1 安裝包秘鑰.zipLinux Centos 7.9 鏡像 2、centos 7.9 下載地址 1、Centos 官網 2、阿里巴巴鏡像站 3、查看網絡命令 ifconfig 或 ip addr 4、登陸服務器 ssh stark192.168.3…

STM32超聲波模塊

一:超聲波模塊1:工作原理采用IO觸發測距,給至少10us的高電平信號。 模塊自動發送8個40KHz的方波,自動檢測是否有信號返回。 有信號返回,通過IO輸出一高電平,高電平持續時間就是超聲波從發射到返回的時間聲波…

RK3568項目(十一)--linux驅動開發之mipi屏幕調試

目錄 一、引言 二、MIPI DSI 屏幕 ------>2.1、MIPI聯盟 ------------>2.1.1、多媒體部分 ------------>2.1.2、硬件協議 ------------>2.1.3、D-PHY功能模式及速率 ------------>2.1.4、分辨率計算 ------>2.2、MIPI-DSI硬件連接 ------>2.3、傳…

C語言小游戲——飛機大戰

目錄 引言 開發環境與工具準備 1. 開發環境配置 2. 資源文件準備 游戲設計與架構 1. 游戲核心數據結構 2. 游戲全局變量 游戲核心功能實現 1. 游戲初始化 2. 游戲主循環 3. 游戲渲染 4. 游戲狀態更新 關鍵游戲機制實現 1. 敵機生成系統 2. 碰撞檢測系統 3. 敵機…

SQLite的可視化界面軟件的安裝

1、如下圖所示,DB Browser軟件,在壓縮包中。2、首先解壓到一個文件夾中。例如(D:\\DB Browser)文件夾。解壓后的內容如下圖。3、將解壓后的DB Browser文件夾,剪切到D:\Program Files\目錄中。如下兩圖。win10操作系統下…

基于 STM32H743VIT6 的邊緣 AI 實踐:貓咪叫聲分類 CNN 網絡部署實戰(已驗證)中一些bug總結

前言前面發了一篇文章基于 STM32H743VIT6 的邊緣 AI 實踐:貓咪叫聲分類 CNN 網絡部署實戰(已驗證)。這里面有一些我遇到過的bug,當時基本都花了很長的時間才解決。這里將這些bug總結一下方便后續查閱。1.使用cubemx插件解析AI模型…

【機器學習】突破分類瓶頸:用邏輯回歸與Softmax回歸解鎖多分類世界

💗💗💗歡迎來到我的博客,你將找到有關如何使用技術解決問題的文章,也會找到某個技術的學習路線。無論你是何種職業,我都希望我的博客對你有所幫助。最后不要忘記訂閱我的博客以獲取最新文章,也歡…

Android gradle plugin agp8.6.1發布時間

Android gradle plugin agp8.6.1發布時間 Android Gradle Plugin (AGP) 的版本 8.6.1 是在2023年發布的。具體來說,它是在2023年4月發布的。這個版本的更新包括了多個重要的改進和修復,旨在提升開發者在Android開發過程中的體驗和效率。 主要更新包括&am…

閉包的兩種設計模式

閉包設計模式 概述 閉包是 JavaScript 中的一個重要概念,它允許內層函數訪問外層函數的變量。在實際開發中,閉包經常被用于實現特定的設計模式,主要包括輔助函數模式和工廠模式。 1. 輔助函數模式(Helper Function Pattern&#x…

力扣119:楊輝三角Ⅱ

力扣119:楊輝三角Ⅱ題目思路代碼題目 給定一個非負索引 rowIndex,返回「楊輝三角」的第 rowIndex 行。 思路 楊輝三角的規律: 第n行有n1個數,n從0開始每行的第一個數和最后一個數都是1。除了第一行的數其他的數都是由它左上角和右上角的…

@Linux自建證書 Nginx+HTTPS

文章目錄Linux自建證書并配置Nginx HTTPS1. 準備工作2. 安裝必要的工具3. 自建證書腳本3.1 創建CA根證書(可選,用于自簽名證書鏈)3.2 創建服務器證書腳本4. 證書文件說明5. 配置Nginx使用HTTPS5.1 創建證書存放目錄5.2 配置Nginx站點5.3 啟用…

解決 RAGFlow報錯 `peewee.OperationalError: (1045)`:MySQL 容器密碼錯誤排查手記

文章目錄 ????♂? 深度排查過程 ?? 完美解決方案:同步真實密碼 ? 驗證結果 ?? 經驗總結與最佳實踐 問題現象: 部署 ragflow 時遭遇以下錯誤,且訪問前端頁面無響應: peewee.OperationalError: (1045, "Access denied for user root@192.168.48.6")關鍵線…

lwIP WebSocket 客戶端 TCP PCB 泄漏問題分析與解決

在嵌入式開發中,使用 lwIP 實現 WebSocket 客戶端時,偶爾會遇到反復連接導致 TCP PCB(Protocol Control Block)泄漏,最終連接數達到上限(如 4)后無法再建立新連接的問題。本文將結合實際案例&am…

k8s之Attach 和 Mount

Attach 和 Mount 一、核心概念對比操作Attach(掛載設備)Mount(掛載文件系統)定義將存儲卷(如 EBS、NFS 等)連接到宿主機將已 Attach 的存儲設備映射為宿主機上的文件系統路徑執行者云提供商驅動&#xff08…

API Gateway HTTP API 控制客戶端訪問 IP 源

前言 在 API Gateway REST API 中我們可以配置 Resource policy 來實現對特定客戶端 IP 地址的限制. 然而 HTTP API 并不提供這個功能, 不過我們可以用 Lambda 搓一個 Authorizer 實現等效的功能. 創建 Lambda authorizer import json import os import ipaddressdef lambda…

Linux搭建LAMP環境(CentOS 7 與 Ubuntu 雙系統教程)

Linux搭建LAMP環境 一、LAMP 環境核心概念 定義:由 Linux、Apache、MySQL、PHP 四大組件組成的開源 Web 應用平臺本質:四個獨立開源軟件的組合體,因長期協同使用形成高度兼容性,成為動態網站和服務器的主流解決方案 二、LAMP 四大…

c# 開機自動啟動程序

以下是兩種實現C#軟件開機自啟動的常用方法&#xff0c;根據需求選擇適合的方案&#xff1a; 方法1&#xff1a;通過注冊表實現&#xff08;需管理員權限&#xff09; using Microsoft.Win32; using System.Diagnostics;public static class AutoStartManager {/// <summa…

C語言---動態內存管理

為什么要有動態內存分配我們在學習動態內存管理之前&#xff0c;一直都是通過開辟變量&#xff0c;或者是開辟數組的方式來在內存的棧區開辟空間的&#xff0c;但是這樣的開辟方式有局限性&#xff0c;因為一旦開辟之后&#xff0c;它們的大小就無法改變&#xff0c;就缺少了很…

C++標準庫(std)詳解

C標準庫&#xff08;std&#xff09;詳解——目錄C標準庫&#xff08;std&#xff09;詳解一、命名空間&#xff08;namespace&#xff09;二、主要組件1. 輸入輸出流&#xff08;<iostream>&#xff09;2. 字符串處理&#xff08;<string>&#xff09;3. STL容器&…