【python】python進階——多線程

引言

????????在現代軟件開發中,程序的執行效率至關重要。無論是處理大量數據、響應用戶交互,還是與外部系統通信,常常需要讓程序同時執行多個任務。Python作為一門功能強大且易于學習的編程語言,提供了多種并發編程方式,其中多線程(Multithreading) 是最常用的技術之一。

一、多線程簡介

1.1 基本概念

  • 線程(Thread):是操作系統能夠進行運算調度的最小單位,它被包含在進程之中,是進程中的實際運作單位。
  • 多線程:指一個進程中同時運行多個線程,每個線程可以執行不同的任務。
  • 并發(Concurrency):多個任務微觀上交替執行,宏觀上給人“同時”運行的錯覺。
  • 并行(Parallelism):多個任務真正同時執行(在多核CPU上)。

1.2 使用多線程的優勢

  • 提高響應性:在GUI應用中,避免界面卡頓。
  • 提高吞吐量:同時處理多個I/O操作(如網絡請求、文件讀寫)。
  • 資源共享:線程共享同一進程的內存空間,通信更高效。

二、Python中的多線程實現

Python標準庫提供了 threading 模塊來支持多線程編程。

創建線程

import threading
import timedef worker(name, delay):print(f"線程 {name} 開始")time.sleep(delay)print(f"線程 {name} 結束")# 創建線程
t1 = threading.Thread(target=worker, args=("A", 2))
t2 = threading.Thread(target=worker, args=("B", 3))# 啟動線程
t1.start()
t2.start()# 等待線程結束
t1.join()
t2.join()print("所有線程執行完畢")

三、線程同步與通信

????????多線程最大的挑戰是共享資源的競爭。當多個線程同時訪問和修改同一數據時,可能導致數據不一致。

3.1 使用?Lock(互斥鎖)

import threading
import time# 共享資源
counter = 0
lock = threading.Lock()def increment():global counterfor _ in range(100000):with lock:  # 自動加鎖和釋放counter += 1# 創建多個線程
threads = []
for i in range(5):t = threading.Thread(target=increment)threads.append(t)t.start()for t in threads:t.join()print(f"最終計數: {counter}")  # 應為 500000

3.2 使用?RLock(可重入鎖)

允許同一線程多次獲取同一把鎖。

lock = threading.RLock()def recursive_func(n):with lock:if n > 0:print(f"遞歸調用: {n}")recursive_func(n - 1)

3.3 使用?Condition(條件變量)

用于線程間的同步協調。

import threading
import timecondition = threading.Condition()
items = []def producer():for i in range(5):with condition:items.append(i)print(f"生產者添加: {i}")condition.notify()  # 通知等待的消費者time.sleep(0.1)def consumer():while True:with condition:while not items:condition.wait()  # 等待通知item = items.pop(0)print(f"消費者取出: {item}")if item == 4:break# 啟動線程
t1 = threading.Thread(target=producer)
t2 = threading.Thread(target=consumer)t1.start()
t2.start()t1.join()
t2.join()

四、線程池

對于需要頻繁創建和銷毀線程的場景,使用線程池可以顯著提升性能。

from concurrent.futures import ThreadPoolExecutor
import requests
import timedef fetch_url(url):response = requests.get(url)return f"{url}: {response.status_code}"urls = ["https://httpbin.org/delay/1","https://httpbin.org/delay/2","https://httpbin.org/delay/1","https://httpbin.org/delay/3"
]# 使用線程池
start_time = time.time()with ThreadPoolExecutor(max_workers=3) as executor:results = list(executor.map(fetch_url, urls))for result in results:print(result)print(f"總耗時: {time.time() - start_time:.2f}秒")

優勢

  • 復用線程,減少創建開銷
  • 控制并發數量
  • 提供更簡潔的API

五、Python多線程的局限性:GIL

5.1 什么是GIL?

全局解釋器鎖(Global Interpreter Lock) 是CPython解釋器的一個互斥鎖,它確保同一時刻只有一個線程執行Python字節碼。

5.2 GIL的影響

  • CPU密集型任務:多線程無法真正并行,性能提升有限。
  • I/O密集型任務:線程在等待I/O時會釋放GIL,因此多線程依然有效。

5.3 如何繞過GIL?

  • 使用?multiprocessing?模塊(多進程)
  • 使用C擴展(如NumPy)
  • 使用Jython或PyPy等其他Python實現

六、最佳實踐與注意事項

6.1 何時使用多線程?

  • I/O密集型任務(網絡請求、文件操作、數據庫查詢)
  • GUI應用中保持界面響應
  • CPU密集型任務(應使用多進程)

6.2 安全注意事項

  • 始終使用鎖保護共享數據
  • 避免死鎖(按固定順序獲取鎖)
  • 盡量減少鎖的持有時間
  • 使用?with?語句確保鎖的釋放

6.3 調試技巧

  • 使用?threading.current_thread()?查看當前線程
  • 使用?threading.active_count()?查看活躍線程數
  • 使用日志記錄線程行為

七、實際應用示例:并發下載器

import threading
import requests
from concurrent.futures import ThreadPoolExecutor
import timedef download_file(url, filename):try:response = requests.get(url, stream=True)with open(filename, 'wb') as f:for chunk in response.iter_content(8192):f.write(chunk)print(f"下載完成: {filename}")except Exception as e:print(f"下載失敗 {filename}: {e}")# 多個文件下載
files = [("https://example.com/file1.zip", "file1.zip"),("https://example.com/file2.zip", "file2.zip"),("https://example.com/file3.zip", "file3.zip"),
]start_time = time.time()with ThreadPoolExecutor(max_workers=3) as executor:for url, filename in files:executor.submit(download_file, url, filename)print(f"全部下載完成,耗時: {time.time() - start_time:.2f}秒")

八、總結

Python多線程是處理I/O密集型任務的強大工具。通過本文的學習,你應該掌握了:

  • 如何創建和管理線程
  • 線程同步機制(Lock, Condition)
  • 使用線程池提升性能
  • 理解GIL的限制
  • 多線程的最佳實踐

雖然GIL限制了Python多線程在CPU密集型任務中的表現,但在I/O密集型場景下,多線程依然是提高程序效率的首選方案。

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

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

相關文章

【JavaEE】(23) 綜合練習--博客系統

一、功能描述 用戶登錄后,可查看所有人的博客。點擊 “查看全文” 可查看該博客完整內容。如果該博客作者是登錄用戶,可以編輯或刪除博客。發表博客的頁面同編輯頁面。 本練習的博客網站,并沒有添加注冊功能,以及上傳作者頭像功能…

MySQL全庫檢索關鍵詞 - idea 工具 Full-Text Search分享

我們經常要在庫中查找一個數據,又不知道在哪個表、哪個字段;或者想找到哪里有在用這個數據。我們可以用:idea 的 Database工具 - Full-Text Search打開idea,在工具欄找到 Database 然后新建自己的連接,然后右鍵&#x…

銀行卡號識別案例

代碼實現:import cv2 import numpy as np import argparse import myutils-i moban.png -t card1.pngap argparse.ArgumentParser() ap.add_argument("-i","--image", requiredTrue,help"path to input image") ap.add_argument(&quo…

云管平臺上線只是開始:從“建好”到“用好”的運營、推廣與深化指南

項目上線的喜悅轉瞬即逝,隨之而來的是一個更為現實和復雜的階段:運營。云管平臺(CMP)的成功,不再僅僅取決于其技術架構的先進性,更在于它能否融入組織的肌理,為不同角色持續創造價值。本文將從管理者、平臺團隊、開發者、運維和財務五個核心角色的視角,深入探討平臺上線…

distributed.client.Client 用戶可調用函數分析

distributed.client.Client 用戶可調用函數分析 1. 核心計算函數 任務提交和執行submit(func, *args, keyNone, workersNone, resourcesNone, retriesNone, priority0, fifo_timeout60s, allow_other_workersFalse, actorFalse, actorsFalse, pureNone, **kwargs) 提交單個函數…

數字圖像處理——信用卡識別

在數字支付時代,信用卡處理自動化技術日益重要。本文介紹如何利用Python和OpenCV實現信用卡數字的自動識別,結合圖像處理與模式識別技術,具有顯著實用價值。系統概述與工作原理信用卡數字識別系統包含兩大核心模塊:模板數字預處理…

嵌入式ARM64 基于RK3588原生SDK添加用戶配置選項./build lunch debian

1 背景 在我們正常拿到SDK后會有一些配置選項,在使用./build.sh lunch之后會輸出一些defautconfig讓我們選擇,瑞芯微的原廠sdk會提供一些主板的配置選項,但是我們的如果是一塊新的主板就需要添加自己的配置選項,本文就討論如何來添…

專為石油和天然氣檢測而開發的基于無人機的OGI相機

專為石油和天然氣檢測而開發的基于無人機的OGI相機基于無人機的 OGI 相機:(Optical Gas Imaging,光學氣體成像)其實是近幾年油氣、電力、化工等行業里非常熱門的應用方向。什么是 OGI 相機OGI(Optical Gas Imaging)&am…

iPhone17全系優缺點分析,加持遠程控制讓你的手機更好用!

知名數碼廠商蘋果,不久前已官宣將于北京時間9月10日凌晨1點開啟發布會,主打對于iPhone 17系列產品介紹,并且和以往不同的是,今年會在購物平臺上開啟線上直播,還是很有新意的。9.13全平臺渠道將開啟預售模式&#xff0c…

人工智能-python-深度學習-神經網絡VGG(詳解)

LeNet 系列之后 —— VGG(詳解):從原理到 PyTorch 實現 文章目錄LeNet 系列之后 —— **VGG(詳解)**:從原理到 PyTorch 實現1. VGG 的發展歷史與意義(一句話+背景)2. VGG…

光伏運維迎來云端革命!AcrelCloud-1200如何破解分布式光伏四大痛點?

在國家“雙碳”目標推動下,分布式光伏正迎來爆發式增長🌞。甘肅、吉林、云南等多地政策接連落地,整縣推進屋頂光伏試點如火如荼!然而,快速發展的背后,你是否也遇到過這些“光伏運維之痛”??【痛…

將 maven 集成到 idea 后出現 向項目創建模塊時出錯:null 的問題

1.出現的問題今天想將maven繼承到idea出現了一下問題:用生成器里面的也會報錯,找了找帖子并沒有哪位大佬出現類似錯誤,于是我解決完想分享一下,如果有不對,請指正。2.解決辦法很可能是java 的 版本 與 maven 版本有問題…

類似于 Progress Telerik Fiddler Classic 的 免費 或 開源 HTTP/HTTPS 抓包與調試工具推薦

以下是一些 類似于 Progress Telerik Fiddler Classic 的 免費 或 開源 HTTP/HTTPS 抓包與調試工具推薦:免費 / 開源替代工具推薦 1. Wireshark 免費且開源的網絡協議分析工具,支持 Windows、macOS、Linux 等平臺。可捕獲并深入分析網絡流量,…

7.0 熱電偶的工作原理

在工業生產過程中,溫度是需要測量和控制的重要參數之一。在溫度測量中,熱電偶的應用極為廣泛,它具有結構簡單、制造方便、測量范圍廣、精度高、慣性小和輸出信號便于遠傳等許多優點。另外,由于熱電偶是一種無源傳感器,…

commons-lang3

概述 提供了許多幫助程序實用程序&#xff0c;特別是字符串操作方法&#xff0c;基本數值方法&#xff0c;對象反射&#xff0c;并發&#xff0c;創建和序列化以及系統屬性。maven依賴<dependency><groupId>org.apache.commons</groupId><artifactId>c…

vue-amap組件呈現的效果圖如何截圖

我們用amap呈現了幾個圖層后&#xff0c;用戶覺得效果很好&#xff0c;想點個按鈕直接將這個畫面截圖下來。 首先我們用Canvas的toDataURL方法可以直接獲取圖像數據&#xff0c;但是實踐發現截圖后是空白的。 原因在警告中&#xff1a; 地圖的WebGL context 的preserveDrawin…

杰理燒錄ERROR: Data error after erasing, address = 0x430000

把CONFIG_BOARD_DEV_KIT關閉&#xff0c;打開CONFIG_BOARD_DEVELOP

超越自動化:為什么說供應鏈的終局是“AI + 人類專家”的混合智能?

摘要&#xff1a;當前&#xff0c;圍繞AI賦能供應鏈的討論&#xff0c;大多聚焦于“自動化”帶來的降本增效。然而&#xff0c;這僅僅是第一層。當我們的系統面對“黑天鵝”事件時&#xff0c;一個過度依賴自動化的“脆弱”系統可能會瞬間崩潰。本文旨在深入探討供應鏈演進的下…

Spine文件導入Unity流程

1、轉為Json文件導出 2、對文件進行處理 3、添加Spine的Package包 一、Spine文件導出設置 1、選擇Json文件 2、選擇導出所在路徑 3、點擊打包設置 更改圖集擴展名 二、文件導出后的設置 1、修改Json的Spine版本 這里必須是3.8 三、下載Unity支持包 1、鏈接 spine-unit…

Docker Compose healthcheck介紹(監控容器中服務的實際健康狀態)數據庫健康檢查pg_isready

文章目錄**功能概述****核心參數詳解****配置示例****1. 基礎用法****2. 使用數據庫健康檢查****3. 結合 depends_on 控制啟動順序****高級用法****1. 自定義健康檢查腳本****2. 多種健康檢查類型**- **HTTP 檢查**&#xff1a;- **TCP 端口檢查**&#xff1a;- **Redis 檢查**…