Python多任務編程:進程全面詳解與實戰指南

1. 進程基礎概念

1.1 什么是進程?

進程(Process)是指正在執行的程序,是程序執行過程中的一次指令、數據集等的集合。簡單來說,進程就是程序的一次執行過程,它是一個動態的概念。

想象你打開電腦上的音樂播放器聽歌,同時又在用瀏覽器上網,這兩個就是不同的進程。操作系統會為每個運行的程序創建一個進程,讓它們看起來像是同時在運行。

1.2 進程的特征

  • 動態性:進程有創建、執行、暫停、終止等生命周期

  • 并發性:多個進程可以同時存在于內存中,在一段時間內交替執行

  • 獨立性:每個進程擁有獨立的地址空間和系統資源

  • 異步性:進程執行速度不可預知,可能隨時被中斷

1.3 進程與程序的區別

區別點程序進程
狀態靜態的代碼集合動態的執行過程
生命周期永久保存暫時存在
資源占用不占用系統資源占用CPU、內存等資源

2. 進程調度算法

操作系統使用調度算法決定哪個進程可以使用CPU資源:

2.1 先來先服務(FCFS)

  • 按照進程到達的順序執行

  • 簡單但不利于短作業

  • 示例:排隊買票,先到先得

processes = ["P1", "P2", "P3"]
for p in processes:print(f"正在執行{p}")

2.2 短作業優先(SJF)

  • 優先執行預計運行時間短的進程

  • 能減少平均等待時間

  • 但難以準確預估作業長度

processes = [("P1",3), ("P2",1), ("P3",2)]
processes.sort(key=lambda x: x[1])  # 按執行時間排序

2.3 時間片輪轉(RR)

  • 每個進程分配一個時間片(如100ms)

  • 時間片用完就切換到下一個進程

  • 公平但上下文切換開銷大

from collections import deque
ready_queue = deque(["P1", "P2", "P3"])
time_slice = 1  # 單位時間while ready_queue:p = ready_queue.popleft()print(f"執行{p} {time_slice}單位時間")ready_queue.append(p)  # 重新加入隊列

2.4 多級反饋隊列

  • 結合了多種算法的優點

  • 設置多個優先級不同的隊列

  • 新進程進入高優先級隊列

  • 長時間運行的進程會被移到低優先級隊列

3. 進程的并行與并發

3.1 基本概念

并行(Parallelism)
指多個任務真正同時執行,需要多核CPU支持。就像餐廳有多個廚師同時做不同的菜。

# 并行示例(假設4核CPU)
from multiprocessing import Pooldef task(n):return n * nif __name__ == '__main__':with Pool(4) as p:  # 創建4個進程print(p.map(task, [1, 2, 3, 4]))  # 4個任務真正同時執行

并發(Concurrency)
指多個任務交替執行,在單核CPU上通過快速切換實現"看似同時"。就像一個廚師輪流做多道菜。

# 并發示例
from multiprocessing import Process
import timedef task(name):print(f"{name}開始")time.sleep(1)print(f"{name}結束")if __name__ == '__main__':processes = []for i in range(3):  # 單核CPU上交替執行p = Process(target=task, args=(f"任務{i}",))p.start()processes.append(p)for p in processes:p.join()

3.2 關鍵區別

特性并行并發
硬件要求需要多核CPU單核即可
執行方式真正同時執行交替執行
效率更高(理想情況)相對較低
適用場景CPU密集型任務I/O密集型任務
圖示🟢🟢🟢(同時進行)🟢→🟡→🔴(快速切換)

3.3 Python中的實現特點

  • GIL限制:由于全局解釋器鎖(GIL),Python多線程無法實現真正的并行,多進程是Python實現并行的主要方式

  • 進程開銷:進程創建和上下文切換開銷比線程大,適合CPU密集型任務

  • multiprocessing模塊:繞過GIL限制,充分利用多核CPU

4. 同步/異步與阻塞/非阻塞

4.1 進程的三種基本狀態

4.2 同步 vs 異步

同步(Synchronous)

  • 像排隊買奶茶,必須等前一個人完成才能輪到你

  • 代碼示例:

from multiprocessing import Process, Lockdef sync_task(lock, num):with lock:  # 同步鎖print(f"進程{num}開始工作")time.sleep(1)print(f"進程{num}結束")if __name__ == '__main__':lock = Lock()for i in range(3):Process(target=sync_task, args=(lock, i)).start()

異步(Asynchronous)

  • 像取號等餐,拿到號后可以去做其他事

  • 代碼示例:

from multiprocessing import Pooldef async_task(num):print(f"開始異步任務{num}")time.sleep(1)return num * 10if __name__ == '__main__':with Pool(3) as p:results = [p.apply_async(async_task, (i,)) for i in range(3)]for res in results:print(res.get())  # 需要時才獲取結果

4.3 阻塞 vs 非阻塞

阻塞(Blocking)

  • 像打電話訂餐,必須等客服回應才能做下一件事

  • 典型表現:join(),?get()等方法會阻塞

p = Process(target=time.sleep, args=(5,))
p.start()
p.join()  # 這里主程序會阻塞等待
print("子進程結束")

非阻塞(Non-blocking)

  • 像發短信訂餐,發完就可以做其他事

  • 典型表現:不調用join()或使用Queuenowait

processes = []
for i in range(3):p = Process(target=time.sleep, args=(i,))p.start()processes.append(p)# 主進程繼續執行其他代碼...
print("主進程繼續運行")# 最后再統一等待
for p in processes:p.join()

4.4 四種組合模式(重點理解)

  1. 同步阻塞

    • 最傳統的方式

    • 示例:直接函數調用,等待返回結果

    result = time.sleep(3)  # 同步調用,阻塞等待
  2. 同步非阻塞

    • 輪詢檢查狀態

    • 示例:檢查進程是否完成

    while True:if not p.is_alive():breaktime.sleep(0.1)
  3. 異步阻塞

    • 較少使用

    • 示例:使用回調但主線程等待

    def callback(result):print("回調結果:", result)with Pool() as pool:res = pool.apply_async(func, args, callback=callback)res.wait()  # 這里又變成了阻塞

  4. 異步非阻塞

    • 最高效的方式

    • 示例:使用進程池+回調

    def callback(result):print("Got result:", result)with Pool() as pool:for i in range(5):pool.apply_async(func=time.sleep,args=(1,),callback=callback)print("主進程繼續執行...")pool.close()pool.join()

4.5 實際應用場景建議

模式適用場景Python實現方式
同步阻塞簡單線性任務直接函數調用
同步非阻塞需要輪詢的任務循環檢查is_alive()
異步阻塞較少使用apply_async+wait()
異步非阻塞高并發I/O操作進程池+回調函數

4.6??完整代碼示例(綜合應用)

"""
多進程模式下載器示例
演示并行、異步非阻塞模式
"""
from multiprocessing import Pool
import time
import randomdef download(url):print(f"開始下載 {url}")time.sleep(random.uniform(1, 3))  # 模擬下載時間print(f"完成下載 {url}")return f"{url}_內容"def save_content(result):print(f"保存結果: {result}")if __name__ == '__main__':urls = ["http://example.com/1","http://example.com/2","http://example.com/3","http://example.com/4"]with Pool(4) as pool:  # 創建進程池# 異步非阻塞模式提交任務results = [pool.apply_async(download, (url,), callback=save_content) for url in urls]print("主進程可以繼續處理其他任務...")# 最終等待所有任務完成pool.close()pool.join()print("所有下載任務完成!")

這個示例展示了:

  1. 并行執行(4個下載任務同時進行)

  2. 異步非阻塞模式(提交任務后立即繼續執行)

  3. 回調機制(下載完成后自動保存)

5. Python中的進程操作

Python通過multiprocessing模塊實現多進程編程,下面介紹幾種創建進程的方式。

5.1 方式一:使用Process類直接創建

from multiprocessing import Process
import osdef func(num):print(f"這是一個普通方法{num}")print(f"我是子進程,我的pid:{os.getpid()},我的父進程編號:{os.getppid()}")if __name__ == '__main__':# 創建進程對象p1 = Process(name="路飛", target=func, args=(1,))# 啟動進程p1.start()# 輸出父進程信息print(f"我是父進程,我的pid:{os.getpid()},我的父進程編號:{os.getppid()}")print(p1)

代碼解析

  1. 導入Process類和os模塊

  2. 定義目標函數func,它將在子進程中執行

  3. 創建Process實例,指定目標函數和參數

  4. 調用start()方法啟動進程

  5. os.getpid()獲取當前進程ID,os.getppid()獲取父進程ID

5.2 方式二:繼承Process類創建

from multiprocessing import Process
import osclass MyProcess(Process):def __init__(self, *args):super(MyProcess, self).__init__()self.args = argsdef run(self):print(f"我是子進程{self.args[0]}")if __name__ == '__main__':p1 = MyProcess(1)p2 = MyProcess(2)p3 = MyProcess(3)p1.start()p2.start()p3.start()

代碼解析

  1. 自定義類繼承Process

  2. 重寫run()方法,定義進程執行邏輯

  3. 創建自定義類的實例并啟動

  4. 這種方式更面向對象,適合復雜任務

5.3 進程常用方法

from multiprocessing import Process
import timedef fun():print("我是子進程")for i in range(3):time.sleep(5)print(f"我是子進程{i}")if __name__ == '__main__':p1 = Process(name='路飛', target=fun)p1.start()p1.join()  # 父進程等待子進程結束for i in range(2):time.sleep(1)print(f"我是父進程{i}")

關鍵方法

  • p.start()啟動進程,并調用該子進程中的p.run()

  • ?p.run ()進程啟動時運行的方法,正是它去調用target 指定的函數,我們自定義類的類中一定要實現該方法
  • p.join([timeout])主線程等待p終止(強調:是主線程處于等的狀態,而p是處于運行的狀態)。

    timeout 是可選的超時時間,需要強調的是, p.join 只能 join start 開啟的進程,而不能 join run 開啟的進程
  • p.is_alive()如果p仍然運行,返回True

  • p.terminate()強制終止進程p,不會進行任何清理操作,如果p創建了子進程,該子進程就成了僵尸進 程。使用該方法需要特別小心這種情況。如果p還保存了一個鎖那么也將不會被釋放,進而導致死鎖

5.4 進程常用屬性

from multiprocessing import Process
import timedef fun():for i in range(10):time.sleep(1)print("我是子進程")if __name__ == '__main__':p = Process(target=fun)p.daemon = True  # 設置為守護進程p.start()time.sleep(5)print("我是父進程")

重要屬性

  • daemon默認值為False,如果設為True,代表p為后臺運行的守護進程,當p的父進程終止時, p也隨之終止,并且設定為True后,p不能創建自己的新進程,必須在p.start()之前設置

    守護進程:跟隨著父進程的代碼執行結束,守護進程就結束
  • name:進程名稱

  • pid:進程ID

  • exitcode進程在運行時為None、如果為–N,表示被信號N結束(了解即可)

6. 進程同步與通信

6.1 進程間數據隔離

from multiprocessing import Processdef work():global nn = 0print('子進程內: ', n)if __name__ == '__main__':n = 100p = Process(target=work)p.start()print('主進程內: ', n)

輸出結果

主進程內: 100
子進程內: 0

解釋:進程間內存空間獨立,修改子進程中的變量不會影響父進程。

7. 實際應用建議

  1. CPU密集型任務:適合使用多進程,可以充分利用多核CPU

  2. I/O密集型任務:多線程可能更合適,避免進程創建開銷

  3. 守護進程:用于執行后臺任務,如日志記錄、監控等

  4. 進程池:當需要創建大量進程時,考慮使用Pool

8. 注意事項

  1. Windows平臺必須使用if __name__ == '__main__':保護主代碼

  2. 進程創建和銷毀開銷較大,不宜創建過多進程

  3. 進程間通信需要使用隊列(Queue)或管道(Pipe)等機制

  4. 避免僵尸進程(子進程結束但父進程未回收資源)

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

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

相關文章

Linux 網絡基礎(二) (傳輸協議層:UDP、TCP)

目錄 一、傳輸層的意義 二、端口號 1、五元組標識一個通信 2、端口號范圍劃分 3、知名端口號(Well-Know Port Number) (1)查看端口號 4、綁定端口號數目問題 5、pidof & netstat 命令 (1)ne…

得佳勝哲訊科技 SAP項目啟動會:膠帶智造新起點 數字轉型新征程

在全球制造業加速向數字化、智能化轉型的浪潮中,膠帶制造行業正迎來以“自動化生產、數據化運營、智能化決策”為核心的新變革。工業互聯網、大數據分析與智能裝備的深度融合,正推動膠帶制造從傳統生產模式向“柔性化生產精準質量控制全鏈路追溯”的智慧…

大數據學習棧記——MapReduce技術

本文介紹hadoop中的MapReduce技術的應用,使用java API。操作系統:Ubuntu24.04。 MapReduce概述 MapReduce概念 MapReduce是一個分布式運算程序的編程框架,核心功能是將用戶編寫的業務邏輯代碼和自帶默認組件整合成一個完整的分布式運算程序…

Centos9 離線安裝 MYSQL8

centos 9 離線安裝 mysql 8 參考教程 1. 官網下載mysql 下載地址 2. 將文件傳輸到Centos中解壓 軟件全部安裝到了/opt中 在opt中新建mysql目錄,解壓到mysql目錄中 tar -xvf mysql壓縮文件 mysql[rootcentoshost mysql]# ls mysql-community-client-8.4.5-1.e…

helm的go模板語法學習

1、helm chart 1.0、什么是helm? 介紹:就是個包管理器。理解為java的maven、linux的yum就好。 安裝方法也可參見官網: https://helm.sh/docs/intro/install 通過前面的演示我們知道,有了helm之后應用的安裝、升級、查看、停止都…

display的一些學習記錄

收集的SDM的log: 01-01 00:00:15.311 933 933 I SDM : Creating Display HW Composer HAL 01-01 00:00:15.311 933 933 I SDM : Scheduler priority settings completed 01-01 00:00:15.311 933 933 I SDM : Configuring RPC threadpool 0…

【Rust 精進之路之第2篇-初體驗】安裝、配置與 Hello Cargo:踏出 Rust 開發第一步

系列: Rust 精進之路:構建可靠、高效軟件的底層邏輯 **作者:**碼覺客 發布日期: 2025-04-20 引言:磨刀不誤砍柴工,裝備先行! 在上一篇文章中,我們一起探索了 Rust 誕生的緣由&…

【深度學習】計算機視覺(17)——ViT理解與應用

文章目錄 Embedding1 概念2 Q&A (1)3 Positional Encoding4 Q&A (2) ViT樣例及Embedding可視化理解1 簡化ViT練習2 CLS Token3 Embedding可視化4 多頭注意力可視化 Embedding技術體系結構參考來源 在研究中對特征的編碼和…

肖特基二極管詳解:原理、作用、應用與選型要點

一、肖特基二極管的基本定義 肖特基二極管(Schottky Diode) 是一種基于金屬-半導體結(肖特基勢壘)的二極管,其核心特性是低正向壓降(Vf≈0.3V)和超快開關速度。 結構特點:陽極采用金…

DeepSeek在數據倉庫的10大應用場景

一、智能數據集成與清洗 多源數據整合:DeepSeek能夠從多種數據源中提取、轉換和加載數據,實現跨系統數據的高效整合。 數據清洗與標準化:通過智能算法自動識別并糾正數據中的錯誤、不一致性和缺失值,提升數據質量。 二、數據倉…

提示詞構成要素對大語言模型跨模態內容生成質量的影響

提示詞構成要素對大語言模型跨模態內容生成質量的影響 提示詞清晰度、具象性與質量正相關 限定指向性要素優于引導指向性要素 大語言模型生成內容保真度偏差 以訊飛星火大模型為實驗平臺,選取100名具備技術素養的人員,從提示詞分類、構成要素和實踐原則歸納出7種提示詞組…

BeautifulSoup 庫的使用——python爬蟲

文章目錄 寫在前面python 爬蟲BeautifulSoup庫是什么BeautifulSoup的安裝解析器對比BeautifulSoup的使用BeautifulSoup 庫中的4種類獲取標簽獲取指定標簽獲取標簽的的子標簽獲取標簽的的父標簽(上行遍歷)獲取標簽的兄弟標簽(平行遍歷)獲取注釋根據條件查找標簽根據CSS選擇器查找…

關于MacOS使用Homebrew的詳細介紹

Homebrew 是 macOS(和 Linux)上最流行的包管理工具(Package Manager),用于快速安裝、更新和管理各種開發工具、命令行程序、開源軟件等。它類似于: Ubuntu/Debian 的 aptCentOS/RHEL 的 yumWindows 的 Cho…

最新扣子空間實操指南

一、首先要先獲取到內部測試的邀請碼, 我們先打開扣子空間官網:https://space.coze.cn/ 輸入邀請碼后進入該頁面: 它這里支持文件上傳,擴展里面有很多插件,頁支持MCP各種插件. 探索模式有兩種,一種是ai自…

ubuntu22.04安裝dukto

1.添加源 sudo add-apt-repository ppa:xuzhen666/dukto2.進行更新和安裝 sudo apt update sudo apt install dukto3.報錯 $ sudo apt install dukto 正在讀取軟件包列表... 完成 正在分析軟件包的依賴關系樹... 完成 正在讀取狀態信息... 完成 您也許需要…

Java編程基礎(第四篇:字符串初次介紹)

前言 HelloWorld寫的多了,語法熟悉一點了吧,其中有段代碼還沒介紹,它就是字符串 public class HelloWorld { public static void main(String[] args) { printBaby(); } static void printBaby() { System.out.print("baby"); } } …

安卓手機怎樣配置數據加速

利用系統自帶功能: 選擇網絡模式:進入手機 “設置”,找到 “網絡” 或 “移動網絡” 選項,點擊 “高級設置”,選擇合適的網絡模式,如優先選擇 4G 或 5G 網絡,以獲得更快的速度。開啟網絡加速功能…

Day3:個人中心頁面布局前端項目uniapp壁紙實戰

接下來我們來弄一下個人中心頁面布局user.vue <template><view class"userLayout"><view class"userInfo"><view class"avatar"><image src"../../static/Kx.jpg" mode"aspectFill"></im…

線性回歸之正則化(regularization)

文章目錄 機器學習中的"防過擬合神器"&#xff1a;正則化全解析1. 正則化&#xff1a;不只是"規矩"那么簡單1.1 魯棒性案例說明 2. L1正則化&#xff1a;冷酷的特征選擇器3. L2正則化&#xff1a;溫柔的約束者4. L1 vs L2&#xff1a;兄弟間的較量5. 正則化…

mapbox基礎,加載視頻到地圖

????? 主頁: gis分享者 ????? 感謝各位大佬 點贊?? 收藏? 留言?? 加關注?! ????? 收錄于專欄:mapbox 從入門到精通 文章目錄 一、??前言1.1 ??mapboxgl.Map 地圖對象1.2 ??mapboxgl.Map style屬性1.3 ??raster 柵格圖層 api二、??加載視頻到…