Python--進程基礎

創建進程

os.fork()

該方法只能在linux和mac os中使用,因為其主要基于系統的fork來實現。window中沒有這個方法。

通過os.fork()方法會創建一個子進程,子進程的程序集為該語句下方的所有語句。

 import os??print("主進程的PID為:" , os.getpid())w = 1pid = os.fork() # 創建子進程print('fork方法的返回值為: ', pid)if pid == 0:print(f'子進程PID: {os.getpid()}, 主進程PID: {os.getppid()}, 子進程中w: {w}')else:print(f'主進程PID: {os.getpid()}, 主進程PID: {os.getppid()}, 子進程中w: {w}')

multiprocessing(target為函數)

通過multiprocessing模塊中的Process類創建一個進程實例對象,并通過其start方法啟動該進程。

進程中的程序集為Process類的target參數,可以是一個函數也可以是一個方法。

需要注意的是windows系統中創建進程的過程需要放在if __name__== "__main__"代碼塊中,因為其實現數據集的復制時,是通過import語句實現。

而在Linux和MacOS系統下則不需要,因為他們原生支持fork方法。

 import multiprocessingimport osimport time?def task():for i in range(3):print("wating... 當前pid為 : ", os.getpid(), "父進程為: ", os.getppid())time.sleep(1)???if __name__ == "__main__":print('主進程pid:', os.getpid())?process = multiprocessing.Process(target=task)process.start()

multiprocessing(taget為方法)

創建Process實例對象的target參數,不僅可以是函數名,還可以是類的方法名。

  • 如果需要往target中傳入參數,可以通過args和kwargs兩個參數進行相應的傳參
 import multiprocessingimport time?class Tasks():def task1(self):time.sleep(1)print('task1')?def task2(self):time.sleep(1)print('task2')?if __name__ == "__main__":t = Tasks()process1 = multiprocessing.Process(target=t.task1)process1.start()?process2 = multiprocessing.Process(target=t.task2)process2.start()

繼承Process類

通過繼承multiprocessing.Process類,并重寫其中的run方法。

  • 必須要重寫run方法,Process子類的實例對象的run方法,就是進程執行的程序
 import timefrom multiprocessing import Process??class MyProcess(Process):def __init__(self, i):super().__init__()self.name = str(i)?def run(self):time.sleep(2)print(f'子進程-{self.name}')??if __name__ == '__main__':for i in range(5):p = MyProcess(i)p.start()?print('主進程')

進程阻塞

目前系統一般都是多核的,當處理多任務時,一般都以并發或并行的方式處理多任務。所以系統一般以異步的方式處理多進程。

Process的實例方法中,通過join方法表示進程阻塞時,主將處于等待狀態,并不會處理其他進程。

單進程阻塞

針對每個進程開啟后立馬啟用join方法,這種方法效率低下。使得系統的處理方式編程同步阻塞,使得主進程依次處理子進程。

 import timefrom multiprocessing import Process?def eat():time.sleep(2)print('eat')?def drink():time.sleep(2)print('drink')?if __name__ == '__main__':process1 = Process(target=eat)process1.start()process1.join()?process2 = Process(target=drink)process2.start()process2.join()??print('主進程')

多進程阻塞

先利用start方法將多個進程同時創建并啟動,然后在創建完成后統一阻塞進程。

  • 統一創建進程,并讓其統一運行
  • 統一等待進程結束,避免每個進程都等一段時間
 import timefrom multiprocessing import Process?def eat():time.sleep(2)print('eat')?def drink():time.sleep(2)print('drink')???if __name__ == '__main__':process1 = Process(target=eat)process1.start()?process2 = Process(target=drink)process2.start()?for p in [process1, process2]:p.join()?print('主進程')

進程鎖

當多進程編輯同一文件或數據時,往往會導致數據不一致問題,針對這種情況,需要在進程中對處理文件或數據的代碼前后進行加鎖和解鎖操作。

如果沒有鎖,會導致數據的不一致

 import time, jsonfrom multiprocessing import Process??def read_ticket(user):with open('ticket.txt') as f:num = json.load(f)['ticket']time.sleep(1)print(f'User {user}: 當前剩余{num}張票')return num??def order_ticket(user, num):time.sleep(1)num -= 1with open('ticket.txt', 'w') as f:json.dump({'ticket': num}, f)print(f'User {user}: 購票成功')??def ticket(user):num = read_ticket(user)if num > 0:order_ticket(user, num)else:print(f'User {user}: 購票失敗')??if __name__ == '__main__':queue = []for i in range(5):p = Process(target=ticket, args=(i,))p.start()queue.append(p)for q in queue:q.join()?print('運行結束')

加鎖/解鎖

在編輯數據的之前通過acquire方法加鎖,當數據編輯完成后,通過release方法解鎖。

  • 在主進程中創建一個鎖對象
  • 然后在每個修改共同數據的進程中傳入已經創建的鎖對象
  • 在修改數據的代碼前后分別加鎖和解鎖
 """@Time: 2024/6/28 20:18@Author: 'Ethan'@Email: ethanzhou4406@outlook.com@File: 1. 同步阻塞.py@Project: python@Feature:"""import time, jsonfrom multiprocessing import Process, Lock??def read_ticket(user):with open('ticket.txt') as f:num = json.load(f)['ticket']time.sleep(0.1)print(f'User {user}: 當前剩余{num}張票')??def order_ticket(user):time.sleep(0.1)with open('ticket.txt') as f:num = json.load(f)['ticket']if num > 0:with open('ticket.txt', 'w') as f:num -= 1json.dump({'ticket': num}, f)print(f'User {user}: 購票成功')else:print(f'User {user}: 購票失敗')??def ticket(user,lock):read_ticket(user)lock.acquire()order_ticket(user)lock.release()??if __name__ == '__main__':lock = Lock()queue = []for i in range(5):p = Process(target=ticket, args=(i, lock))p.start()queue.append(p)for q in queue:q.join()?print('運行結束')?

鎖的上下文管理器

如果在代碼加鎖后,解鎖前,代碼出現了異常就會導致進程沒有來得及解鎖,而導致死鎖現象。通過鎖的上下文管理器語法,可以有效避免這種情況的發生。

 import time, jsonfrom multiprocessing import Process, Lock??def read_ticket(user):with open('ticket.txt') as f:num = json.load(f)['ticket']time.sleep(0.1)print(f'User {user}: 當前剩余{num}張票')??def order_ticket(user):time.sleep(0.1)with open('ticket.txt') as f:num = json.load(f)['ticket']if num > 0:with open('ticket.txt', 'w') as f:num -= 1json.dump({'ticket': num}, f)print(f'User {user}: 購票成功')else:print(f'User {user}: 購票失敗')??def ticket(user,lock):read_ticket(user)with lock:order_ticket(user)??if __name__ == '__main__':lock = Lock()queue = []for i in range(5):p = Process(target=ticket, args=(i, lock))p.start()queue.append(p)for q in queue:q.join()?print('運行結束')?

進程間通信

進程之間可以進行通信,主要是通過各個進程之中傳入一個公共的溝通工具,所有的進程都通過這個工具進行溝通。multiprocessing中提供了兩種進程間溝通的工具QueuePipe

Queue方式

Queue是基于文件傳輸的socket通信方式,并且它是帶鎖機制的。它的數據主要的特點是先進先出,后進后出。

當一個對象被放入一個隊列中時,這個對象首先會被一個后臺線程用pickle序列化,并將序列化后的數據通過一個底層管道的管道傳遞給隊列中。

主要使用如下方法:

  • qsize(): 返回隊列的大致的長度。返回的值由于多線程或多進程的上下文而變得不可靠
  • empty(): 隊列為空返回True,否則返回False。返回的值由于多線程或多進程的上下文而變得不可靠
  • full(): 隊列滿了返回True,否則返回False。返回的值由于多線程或多進程的上下文而變得不可靠
  • put(obj[, block[, timeout]]): 將obj放入隊列。
    • 如果block為True(默認值)而且timeout是None(默認值),將會阻塞當前進程,直到有空的緩沖槽。
    • 如果timeout是正數,將會阻塞了最多timeout秒之后還是沒有可用的緩沖槽時拋出queue.Full異常
    • 反之block為False,僅當有可用緩沖槽時才放入對象,否則拋出queue.Full異常(這種情況下timeout參數會被忽略)

  • get([block[, timeout]]): 從隊列中取出并返回對象。如果可選參數block是True而且timeout是None,將會阻塞當前進程,直到隊列中出現可用對象。如果timeout是正數,將會阻塞了最多timeout秒之后還是沒有可用的對象時拋出queue.Empty異常。
    • 反之,block是False時,僅當有可用對象能夠取出時返回,否則拋出queue.Empty異常(這種情況下timeout參數會被忽略)

 import time, jsonfrom multiprocessing import Process, Queue??def task(i, queue: Queue):time.sleep(1)queue.put(i)print(f'task {i}, 入列')??if __name__ == '__main__':queue = Queue()process_queue = []for i in range(5):p = Process(target=task, args=(i, queue))p.start()process_queue.append(p)for p in process_queue:p.join()?for i in range(5):print(f'主進程中消費隊列內容{queue.get()}')?print('運行結束')?

Pipe方式

Pipe方式是進程之間通信的另一種方式和Queue不同之處在于,它不帶鎖,且信息順序無法得到保障。

主要的使用方法:

  • send(obj): 將一個對象發送到鏈接的另一端,可以用recv()讀取,發送的對象必須是可序列化的,多大的對象(接近32MiB)可能引發ValueError異常
  • recv(): 返回一個由另一端使用send()發送的對象,該方法會一直阻塞直到接收到對象。如果對端關閉了鏈接或者沒有東西可接收,將拋出EOFError異常
 import timefrom multiprocessing import Process, Pipefrom multiprocessing.connection import Connection??def task(pipe:Connection):print('子進程往管道里加了內容')time.sleep(1)pipe.send("子進程往管道中加了點東西")??if __name__ == '__main__':pipe1, pipe2 = Pipe()p = Process(target=task, args=(pipe1,))p.start()p.join()print('主進程中獲取管道內的內容為:', pipe2.recv())print('運行結束')

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

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

相關文章

Python pdfkit wkhtmltopdf html轉換pdf 黑體字體亂碼

wkhtmltopdf 黑體在html轉換pdf時&#xff0c;黑體亂碼&#xff0c;分析可能wkhtmltopdf對黑體字體不太兼容&#xff1b; 1.html內容如下 <html> <head> <meta http-equiv"content-type" content"text/html;charsetutf-8"> </head&…

DreamView數據流

DreamView數據流 查看DV中界面啟動dag&#xff0c;/apollo/modules/dreamview_plus/conf/hmi_modes/pnc.pb.txt可以看到點擊界面的planning按鈕&#xff0c;后臺其實啟動的是/apollo/modules/planning/planning_component/dag/planning.dag和/apollo/modules/external_command…

語音識別應用Python示例

語音識別是將語音信號轉換為文本的技術&#xff0c;是人工智能領域的重要研究方向之一。下面是一個基于Python的簡單語音識別應用的代碼示例。 首先&#xff0c;需要安裝Python的語音識別庫SpeechRecognition。可以使用以下命令進行安裝&#xff1a; pip install SpeechRecog…

版本號比較

版本號比較&#xff1a; 注意&#xff1a; 不可以直接使用字符串比較的方法進行版本號比較。例如 2.29.1 > 2.3.0 是 false 的 版本號比較可以參考以下代碼&#xff1a; function compareVersion(v1, v2) {v1 v1.split(.)v2 v2.split(.)const len Math.max(v1.length, …

Oracle連接mysql

oracle使用的11g&#xff0c;在一臺windows服務器&#xff1b;mysql使用的是5.7版本&#xff0c;在另一臺windows服務器&#xff0c;這兩個服務器之間的網絡是互通的。做BI時&#xff0c;要獲取不同數據源的數據&#xff0c;這些數據源可能是Oracle&#xff0c;也可能是sqlserv…

springboot基礎入門2(profile應用)

Profile應用 一、何為Profile二、profile配置方式1.多profile文件方式2.yml多文檔方式 三、加載順序1. file:./config/: 當前項目下的/config目錄下2. file:./ &#xff1a;當前項目的根目錄3. classpath:/config/:classpath的/config目錄4. classpath:/ : classpath的根目錄 四…

【設計模式】【創建型5-2】【工廠方法模式】

文章目錄 工廠方法模式工廠方法模式的結構示例產品接口具體產品工廠接口具體工廠客戶端代碼 實際的使用 工廠方法模式 工廠方法模式的結構 產品&#xff08;Product&#xff09;&#xff1a;定義工廠方法所創建的對象的接口。 具體產品&#xff08;ConcreteProduct&#xff0…

Redis 集群模式

一、集群模式概述 Redis 中哨兵模式雖然提高了系統的可用性&#xff0c;但是真正存儲數據的還是主節點和從節點&#xff0c;并且每個節點都存儲了全量的數據&#xff0c;此時&#xff0c;如果數據量過大&#xff0c;接近或超出了 主節點 / 從節點機器的物理內存&#xff0c;就…

個人網站制作 Part 28 添加用戶活動跟蹤功能 | Web開發項目添加頁面緩存

文章目錄 &#x1f469;?&#x1f4bb; 基礎Web開發練手項目系列&#xff1a;個人網站制作&#x1f680; 添加用戶活動跟蹤功能&#x1f528;使用分析工具&#x1f527;步驟 1: 選擇分析工具&#x1f527;步驟 2: 注冊Google Analytics賬戶&#x1f527;步驟 3: 獲取Analytics…

Java面試題--JVM大廠篇之深入了解G1 GC:高并發、響應時間敏感應用的最佳選擇

引言&#xff1a; 在現代Java應用的性能優化中&#xff0c;垃圾回收器&#xff08;GC&#xff09;的選擇至關重要。對于高并發、響應時間敏感的應用而言&#xff0c;G1 GC&#xff08;Garbage-First Garbage Collector&#xff09;無疑是一個強大的工具。本文將深入探討G1 GC適…

李一桐遭遇蜈蚣驚魂

李一桐遭遇“蜈蚣驚魂”&#xff01;劉宇寧展現真男人本色在娛樂圈的幕后&#xff0c;總有一些心跳加速的驚險。近日&#xff0c;李一桐在拍戲時遭遇了一場“蜈蚣驚魂”&#xff0c;讓無數粉絲和網友為她捏了一把冷汗。而在這場驚險的遭遇中&#xff0c;劉宇寧展現出了真男人的…

NOI大綱——普及組——二叉搜索樹

二叉搜索樹 二叉搜索樹&#xff08;Binary Search Tree&#xff0c;簡稱BST&#xff09;是一種特殊的二叉樹&#xff0c;它具有以下幾個特點&#xff1a; 節點的左子樹上的所有節點的值都小于或等于該節點的值。節點的右子樹上的所有節點的值都大于或等于該節點的值。每個節點…

ActiveMq工具之管理頁面說明

文章目錄 安裝ActiveMQ一: 訪問管理頁面二: 進入管理頁面&#xff0c;主頁三: Queues頁說明四: Topics頁說明五: Subscribers頁說明 安裝ActiveMQ wget https://archive.apache.org/dist//activemq/5.13.3/apache-activemq-5.13.3-bin.tar.gz wget https://mirrors.huaweiclou…

為什么越來越多的企業選擇外包?賦能企業未來

軟件開發過程包括設計需求、設計方案、產品研發、產品交付、后期維護&#xff0c;許多企業并沒有軟件開發的專業能力與工作經驗&#xff0c;將軟件開發工作進行外包是比較節約成本的&#xff0c;企業能少走不少彎路。 YesPMP平臺&#xff08;一站式軟件外包、項目外包服務-YesP…

UWA Pipeline 2.6.1版本更新

UWA Pipeline是專為游戲開發團隊設計的本地協作平臺&#xff0c;旨在幫助團隊建立專業的DevOps研發交付流水線。本平臺提供了可視化的CI/CD操作界面&#xff0c;高可用的自動化測試和無縫集成的UWA性能保障服務等核心功能。 在最新的Pipeline更新中&#xff0c;UWA引入了參數配…

protobufjs解析proto消息出錯RangeError: index out of range: 2499 + 10 > 2499解決辦法

使用websocket通訊傳輸protobuf消息的時候&#xff0c;decode的時候出錯了&#xff1a; RangeError: index out of range: 2499 10 > 2499 Error: invalid wire type 4 at offset 1986 出現這種錯誤的時候&#xff0c;99%是因為proto里面的消息類型和服務端發送的消息類型不…

vue表頭字段添加鼠標懸浮提示

<el-table-column prop"jfScore" align"center" min-width"100px"><template slot"header" slot-scope"scope"><div><span>信用積分</span><el-tooltip:aa"scope"class"it…

Java錯題歸納(二)

1、若有如下接口A的定義&#xff0c;下列哪些類下確實現了該接口&#xff1a;C interface A { void method1(int i); void method2(int j); } A class B implements A{ void method1( ) { } void method2( ) { } } B class B implements A { void method1(int i ) { }…

關于windows,wifi圖標顯示不了的解決方法

解決方法一&#xff08;解決了我的問題的方法&#xff09;&#xff1a; winr -->輸入 regedit 打開注冊表 --> 刪除HKEY-CLASSES_ROOT\CLSID\{3d09c1ca-2bcc-40b7-b9bb-3f3ec143a87b} CLSID在下面仔細找&#xff0c;然后找到09開頭那個刪掉重啟就可以了&#xff0c;可能…

別小看ai智能語音機器人但也別神話它電銷機器人部署語音識別‘次數活動

人類社會的發展不斷在加速&#xff0c;現代人對新事物接納的速度變得越來越快&#xff0c;進而對新事物、新模式的期待也越來越多、頻率越來越高。 僅聚焦在電銷領域&#xff0c;當將視線回撥&#xff0c;我們會發現作為新技術與新模式的代表&#xff0c;電銷從20世紀中后期引進…