Python進行threading多線程編程及高級并發處理機制

threading 模塊是 Python 中用于進行多線程編程的標準庫之一。通過 threading 模塊,你可以創建和管理線程,使得程序能夠并發執行多個任務。以下是一些基本的 threading 模塊的用法:

1. 創建線程:

使用 threading.Thread 類可以創建一個新的線程。需要提供一個可調用對象(通常是一個函數),作為線程的執行體。

import threadingdef my_function():for _ in range(5):print("Hello from thread!")# 創建線程
my_thread = threading.Thread(target=my_function)# 啟動線程
my_thread.start()# 主線程繼續執行其他任務
for _ in range(5):print("Hello from main thread!")

2. 線程同步:

在多線程編程中,為了防止多個線程同時訪問共享的資源,可以使用鎖(threading.Lock)進行線程同步。

import threading# 共享資源
counter = 0
counter_lock = threading.Lock()def increment_counter():global counterfor _ in range(1000000):with counter_lock:counter += 1# 創建兩個線程
thread1 = threading.Thread(target=increment_counter)
thread2 = threading.Thread(target=increment_counter)# 啟動線程
thread1.start()
thread2.start()# 等待兩個線程結束
thread1.join()
thread2.join()print("Counter:", counter)

3. 線程間通信:

在多線程編程中,線程之間可能需要進行通信。可以使用 threading.Eventqueue.Queue 等機制來實現線程間的通信。

使用 threading.Event
import threadingdef wait_for_event(event):print("Waiting for event to be set")event.wait()print("Event has been set")def set_event(event, delay):print(f"Waiting for {delay} seconds before setting the event")threading.Event().wait(delay)event.set()print("Event has been set")# 創建事件對象
event = threading.Event()# 創建兩個線程
thread1 = threading.Thread(target=wait_for_event, args=(event,))
thread2 = threading.Thread(target=set_event, args=(event, 2))# 啟動線程
thread1.start()
thread2.start()# 等待兩個線程結束
thread1.join()
thread2.join()

?使用 queue.Queue

import threading
import queuedef producer(queue, items):for item in items:queue.put(item)def consumer(queue):while True:item = queue.get()if item is None:breakprint(f"Consumed: {item}")# 創建隊列對象
my_queue = queue.Queue()# 創建兩個線程
producer_thread = threading.Thread(target=producer, args=(my_queue, range(5)))
consumer_thread = threading.Thread(target=consumer, args=(my_queue,))# 啟動線程
producer_thread.start()
consumer_thread.start()# 等待生產者線程結束
producer_thread.join()# 放置一個特殊值到隊列中,表示消費者可以停止
my_queue.put(None)# 等待消費者線程結束
consumer_thread.join()

4.注意事項:

  • 盡量避免使用全局變量,或者確保在多線程操作時使用適當的同步機制(如鎖)。
  • 謹慎使用共享資源,確保在多線程環境中正確管理資源。
  • 注意線程間的通信和同步,以防止數據競爭和死鎖。

雖然 threading 模塊提供了簡單的多線程編程接口,但在一些場景中,使用 concurrent.futures 模塊中的 ThreadPoolExecutorProcessPoolExecutor 類更加方便,它們提供了高級的并發處理機制。

concurrent.futures 模塊提供了更高級的并發處理機制,其中的 ThreadPoolExecutorProcessPoolExecutor 類是兩個常用的工具,分別用于線程池和進程池的并發執行。這兩個類都是 concurrent.futures.Executor 的子類。

5.線程池ThreadPoolExecutor

ThreadPoolExecutor 提供了一個線程池,可以方便地在多個線程中執行函數。以下是一個簡單的示例:

from concurrent.futures import ThreadPoolExecutor
import timedef my_function(message):time.sleep(2)return f"Hello, {message}!"# 創建線程池
with ThreadPoolExecutor(max_workers=3) as executor:# 提交任務并獲取 Future 對象future1 = executor.submit(my_function, "Alice")future2 = executor.submit(my_function, "Bob")# 阻塞等待任務完成并獲取結果result1 = future1.result()result2 = future2.result()print(result1)
print(result2)

上述代碼中,ThreadPoolExecutor 創建了一個最大工作線程數為 3 的線程池,通過 submit 方法提交了兩個任務,然后通過 result 方法獲取任務的結果。

6.進程池ProcessPoolExecutor

ProcessPoolExecutor 提供了一個進程池,可以在多個進程中執行函數。同樣是一個示例:

from concurrent.futures import ProcessPoolExecutor
import timedef my_function(message):time.sleep(2)return f"Hello, {message}!"# 創建進程池
with ProcessPoolExecutor(max_workers=3) as executor:# 提交任務并獲取 Future 對象future1 = executor.submit(my_function, "Alice")future2 = executor.submit(my_function, "Bob")# 阻塞等待任務完成并獲取結果result1 = future1.result()result2 = future2.result()print(result1)
print(result2)

這段代碼與上一個示例類似,不同之處在于使用了 ProcessPoolExecutor 創建了一個進程池,任務在不同的進程中執行。這使得它適用于一些 CPU 密集型的任務,可以充分利用多核處理器的性能。

7.并發處理的優勢:

  1. 簡化并發編程: concurrent.futures 模塊提供了更高層次的接口,簡化了并發編程的復雜性。

  2. 易于管理任務: 使用 submit 方法可以方便地提交任務,并通過 Future 對象進行管理。

  3. 自動管理資源: 使用 with 語句創建 ThreadPoolExecutorProcessPoolExecutor 時,會自動管理資源的生命周期,不再需要手動管理線程或進程的啟動和關閉。

  4. 可替代傳統的 threadingmultiprocessing 模塊: 在某些場景下,concurrent.futures 提供了更方便的方式來進行并發編程,特別是對于一些簡單的并行任務。

在實際應用中,選擇使用 concurrent.futures 模塊還是傳統的 threadingmultiprocessing 模塊,取決于具體的需求和場景。如果你只是簡單地執行一些任務,并發處理的復雜性較低,使用 concurrent.futures 可能更加方便。而對于更復雜的并發控制和線程/進程管理,傳統的 threadingmultiprocessing 模塊可能更適合。

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

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

相關文章

在兩個java項目中實現Redis的發布訂閱模式

如何在兩個java項目中實現Redis的發布訂閱模式? 1. Redis簡介2. 發布訂閱模式介紹3. 實現思路4. 代碼實現及詳細解釋4.1. RedisUtil4.2. Publisher4.3. Subscriber4.4. 運行程序 目錄: Redis簡介發布訂閱模式介紹實現思路代碼實現及詳細解釋 1. Redis簡…

HTB Napper WriteUp

Napper 2023年11月12日 14:58:35User Nmap ? Napper nmap -sCV -A -p- 10.10.11.240 --min-rate 10000 Starting Nmap 7.80 ( https://nmap.org ) at 2023-11-12 13:58 CST Nmap scan report for app.napper.htb (10.10.11.240) Host is up (0.15s latency). Not shown: …

gitee推薦-SAPI++

一下內容來自gitee。 SaaS-Apps-Engine: 智者|SAPI是多應用、多租戶SaaS應用引擎,支持(小程序/公眾號/輕應用/企微/抖音/支付寶/百度)等多平臺應用。基于ThinkPHP6.1/8.0原生多應用模式開發,簡潔、高效、易擴展。集成強大的權限控…

適用于電腦的5個免費文件恢復軟件分享

適用于電腦的最佳免費文件恢復軟件 任何計算機用戶都可能經歷過丟失重要文件的恐懼。重要數據的丟失可能會令人不安和沮喪,無論是由于不小心刪除、計算機故障還是硬盤格式化造成的。幸運的是,在數字時代,您可以使用值得信賴的解決方案檢索這些…

好工具|datamap,一個好用的地圖可視化Excel插件,在Excel中實現地理編碼、拾取坐標

在做VRP相關研究的時候,需要對地圖數據做很多處理,比如地理編碼,根據“重慶市沙坪壩區沙正街174號”這樣的一個文本地址知道他的經緯度;再比如繪制一些散點圖,根據某個位置的經緯度在地圖上把它標注出來。還有有的時候…

vue + docxtemplater 導出 word 文檔

一、痛點 word 導出 這種功能其實之前都是后端實現的,但最近有個項目沒得后端。所以研究下前端導出。 ps: 前端還可以導出 pdf,但是其分頁問題需要話精力去計算才可能實現,并且都不是很完善。可參考之前的文章:利用 h…

MIT6.824-Raft筆記:腦裂、Majority Vote(過半投票/過半選舉)

本部分主要是問題引入,以及給出一個解決方案 1 腦裂(Split Brain) replication system的共同點:單點 前面幾個容錯特性(fault-tolerant)的系統,有一個共同的特點。 MapReduce復制了計算&…

JavaScript框架 Angular、React、Vue.js 的全棧解決方案比較

在 Web 開發領域,JavaScript 提供大量技術棧可供選擇。其中最典型的三套組合,分別是 MERN、MEAN 和 MEVN。前端框架(React、Angular 和 Vue)進行簡化比較。 MERN 技術棧詳解 MERN 技術棧包含四大具體組件: MongoDB&am…

藍橋杯物聯網競賽_STM32L071_3_Oled顯示

地位: 對于任何一門編程語言的學習,print函數毫無疑問是一種最好的調試手段,調試者不僅能通過它獲取程序變量的運行狀態而且通過對其合理使用獲取程序的運行流程,更能通過關鍵變量的輸出幫你驗證推理的正確與否,樸素的…

常見網絡安全防護

1 阻斷服務攻擊(DOS) 阻斷服務攻擊,想辦法目標網絡資源用盡變種:分布式阻斷服務攻擊 影響: 寬帶消耗性(消耗目標的帶寬)資源消耗型(消耗目標的計算資源) 解決方案&am…

人工智能對網絡安全的影響越來越大

如果問當前IT行業最熱門的話題是什么,很少有人會回答除了人工智能(AI)之外的任何話題。 在不到 12 個月的時間里,人工智能已經從一項只有 IT 專業人員才能理解的技術發展成為從小學生到作家、程序員和藝術家的每個人都使用的工具…

MySQL索引事務基礎

目錄 1. 索引 1.1索引的概念 1.2索引的特點 1.3 索引的使用場景 1.4索引的使用 1.4.1查看索引 1.4.2創建索引 1.4.3刪除索引 1.5索引保存的數據結構 2.事務 2.1經典例子 2.2事務的概念 2.3事務的使用 2.4事務的4個核心特性 2.5事務的并發問題 2.5.1臟讀 2.5.2不可…

Python + Docker 還是 Rust + WebAssembly?

在不斷發展的技術世界中,由大語言模型驅動的應用程序,通常被稱為“LLM 應用”,已成為各種行業技術創新背后的驅動力。隨著這些應用程序的普及,用戶需求的大量涌入對底層基礎設施的性能、安全性和可靠性提出了新的挑戰。 Python 和…

Java項目如何打包成Jar(最簡單)

最簡單的辦法,使用Maven插件(idea自帶) 1.選擇需要打包的mudule,點擊idea右側的maven插件 2.clean操作 3.選擇需要的其他mudule,進行install操作(如果有) 4.再次選擇需要打包的module&#…

Vue.observable 是什么

Observable 翻譯過來我們可以理解成可觀察的 Vue.js2.6 新增 Vue.observable,讓一個對象變成響應式數據。Vue 內部會用它來處理 data 函數返回的對象 。 返回的對象可以直接用于渲染函數和計算屬性內,并且會在發生變更時觸發相應的更新。也可以作為最小化…

Git的指令

Git 各平臺安裝包下載地址為:http://git-scm.com/downloads Ubuntu Git 安裝命令為: $ apt-get install git用戶信息 配置個人的用戶名稱和電子郵件地址: $ git config --global user.name "runoob" $ git config --global user.…

Python----類對象和實例對象

目錄 一.類和類的實例 二.類屬性和實例屬性 三.私有屬性和公有屬性 四.靜態方法和類方法 五.__init__方法,__new__方法和__del__方法: 六.私有方法和公有方法 七.方法的重載 八.方法的繼承 九.方法的重寫 十.對象的特殊方法 十一.對象的引用&a…

軟件開發模式開源和閉源的優劣之爭

開源和閉源,兩種截然不同的開發模式,對于大模型的發展有著重要影響。開源讓技術共享,吸引了眾多人才加入,推動了大模的創新。而閉源則保護了商業利益和技術優勢,為大模型的商業應用提供了更好的保障。 開源與閉源軟件的…

基于命令行模式設計退款請求處理

前言 這篇文章的業務背景是基于我的另一篇文章: 對接蘋果支付退款退單接口-CSDN博客 然后就是說設計模式是很開放的東西,可能我覺得合適,你可能覺得不合適,這里只是做下討論,沒有一定要各位同意的意思.... 相關圖文件 這里我先把相關的圖文件放上來,可能看著會比較清晰點 代碼邏…

sql之left join、right join、inner join的區別

sql之left join、right join、inner join的區別 left join(左聯接) 返回包括左表中的所有記錄和右表中聯結字段相等的記錄 right join(右聯接) 返回包括右表中的所有記錄和左表中聯結字段相等的記錄 inner join(等值連接) 只返回兩個表中聯結字段相等的行 舉例如下&#xff1…