簡單介紹python process模組

大雄45發表於2021-05-28
導讀 在python中大部分情況需要使用多程式,python提供了multiprocessing模組。multiprocessing模組的功能眾多:支援子程式、通訊和共享資料、執行不同形式的同步,提供了Process、Queue、Pipe、Lock等元件。本文將著重講解process模組的使用
process模組

process模組是一個建立程式的模組,藉助這個模組,就可以完成程式的建立。

引數介紹:

Process(group=None, target=None, name=None, args=(), kwargs={})
1 group——引數未使用,值始終為None
2 target——表示呼叫物件,即子程式要執行的任務
3 args——表示呼叫物件的位置引數元組,args=(1,2,'egon',)
4 kwargs——表示呼叫物件的字典,kwargs={'name':'egon','age':18}
5 name——為子程式的名稱

方法介紹:

obj.start():啟動程式,並呼叫該子程式中的obj.run()
obj.run():程式啟動時執行的方法,正是它去呼叫target指定的函式,我們自定義類的類中一定要實現該方法
obj.terminate():強制終止程式obj,不會進行任何清理操作,如果obj建立了子程式,該子程式就成了殭屍程式,使用該方法需要特別小心這種情況。如果obj還儲存了一個鎖那麼也將不會被釋放,進而導致死鎖
obj.is_alive():如果obj仍然執行,返回True
obj.join([timeout]):主執行緒等待obj終止(強調:是主執行緒處於等的狀態,而obj是處於執行的狀態)。timeout是可選的超時時間,需要強調的是,obj.join只能join住start開啟的程式,而不能join住run開啟的程式

屬性介紹:

obj.daemon:預設值為False,如果設為True,代表obj為後臺執行的守護程式,當obj的父程式終止時,obj也隨之終止,並且設定為True後,obj不能建立自己的新程式,必須在obj.start()之前設定
obj.name:程式的名稱
obj.pid:程式的pid
obj.exitcode:程式在執行時為None、如果為–N,表示被訊號N結束(瞭解即可)
obj.authkey:程式的身份驗證鍵,預設是由os.urandom()隨機生成的32字元的字串。這個鍵的用途是為涉及網路連線的底層程式間通訊提供安全性,這類連線只有在具有相同的身份驗證鍵時才能成功(瞭解即可)
1、在python中啟動一個子程式
from multiprocessing import Process
import os
def func():
    print('這是一個子程式——>程式號:', os.getpid(), '  主程式號:', os.getppid())
if __name__ == '__main__':
    print('這是主程式——>程式號:', os.getpid(), '  主程式號(pycharm):', os.getppid())
    # 例項化一個子程式物件
    obj = Process(target=func)
    obj.start()     # 執行子程式物件
    print('執行了完了主程式的內容')
# 輸出
這是主程式——>程式號: 3100   主程式號(pycharm): 6748
執行了完了主程式的內容
這是一個子程式——>程式號: 2392   主程式號: 3100
2、給子程式傳遞引數
from multiprocessing import Process
import os
def func(name, age):
    print('這是一個子程式——>程式號:', os.getpid(), '  主程式號:', os.getppid())
    print(f'這是一個子程式——>我的名字是{name},今年{age}')
if __name__ == '__main__':
    print('這是主程式——>程式號:', os.getpid(), '  主程式號(pycharm):', os.getppid())
    # 例項化一個子程式物件
    obj = Process(target=func, args=('小楊', '18')) # args以元組的形式給子程式func函式傳位置引數
                               # kwargs以字典的形式給子程式func函式傳關鍵字引數
                               # kwargs={'name': '小楊', 'age': 18}
    obj.start()     # 執行子程式物件
    print('執行了完了主程式的內容')
     
# 輸出
這是主程式——>程式號: 11936   主程式號(pycharm): 3676
執行了完了主程式的內容
這是一個子程式——>程式號: 2996   主程式號: 11936
這是一個子程式——>我的名字是小楊,今年18
3、同時開多個子程式
from multiprocessing import Process
import os
def func(name, age):
    print(f'這是一個子程式——>程式號:{os.getpid()},主程式號:{os.getppid()},我的名字是{name},今年{age}')
if __name__ == '__main__':
    print('這是主程式——>程式號:', os.getpid(), '  主程式號(pycharm):', os.getppid())
    count = [('小楊', 18), ('鮑勃', 20), ('艾倫', 55)]
    for lis in count:
        # 例項化一個子程式物件
        obj = Process(target=func, args=lis)   # args以元組的形式給子程式func函式傳位置引數
        obj.start()     # 執行子程式物件
    print('執行了完了主程式的內容')
     
# 輸出
這是主程式——>程式號: 12632   主程式號(pycharm): 9220
執行了完了主程式的內容
這是一個子程式——>程式號:10048,主程式號:12632,我的名字是小楊,今年18
這是一個子程式——>程式號:16032,主程式號:12632,我的名字是鮑勃,今年20
這是一個子程式——>程式號:12060,主程式號:12632,我的名字是艾倫,今年55
4、join的用法

obj.join([timeout]): 主程式等待子程式obj終止(強調:是主程式處於等的狀態,而子程式obj是處於執行的狀態)。timeout是可選的超時時間,需要強調的是,obj.join只能join住start開啟的程式,而不能join住run開啟的程式

多個程式同時執行(注意,子程式的執行順序不是根據啟動順序決定的)

join——>屬於同步阻塞:

同步:在做A事件的時候發起B事件,必須等待B事件結束後才能繼續做A事件

阻塞:CPU不工作——>input accept recv recvfrom sleep connect......

start——>屬於非同步非阻塞:

非同步:在做A事件的時候發起B事件,不用等待B事件結束就可以繼續A事件

非阻塞:CPU在工作(非輸入輸出階段I/O)

from multiprocessing import Process
import random
import time
def mail(name, age):
    count = random.random()
    print(f'給{age}歲的{name}發了一封郵件!延遲{count}秒')
    time.sleep(count)      # 模擬網路延遲
    """
    多個程式同時執行(注意,子程式的執行順序不是根據啟動順序決定的)
    """
if __name__ == '__main__':
    info_list = [('小楊', 18), ('鮑勃', 20), ('艾倫', 55)]
    jo = []
    for info in info_list:
        obj = Process(target=mail, args=info)
        obj.start()
        jo.append(obj)
    # 將所有的子程式全部放入jo列表,在迴圈join所有子程式,就能等待所有子程式結束後在做操作
    for o in jo:
        o.join()
    # 所有的子程式結束的操作
    print('全部傳送完畢')
     
# 輸出
給20歲的鮑勃發了一封郵件!延遲0.19840279388911186秒
給18歲的小楊發了一封郵件!延遲0.8891892863366903秒
給55歲的艾倫發了一封郵件!延遲0.0434307277609951秒
全部傳送完畢
5、多程式之間的資料是否隔離
from multiprocessing import Process
count = 1
def func():
    global count
    count += 1
if __name__ == '__main__':
    for i in range(10):
        obj = Process(target=func)
        obj.start()
    print(count)        # ————>1 主程式的count沒有被改變說明程式之間的資料時隔離的
     
# 輸出
1
6、為什麼在Windows中Process()必須放到if __name__ == '__main__':下

由於Windows沒有fork,多處理模組啟動一個新的Python程式並匯入呼叫模組。

如果在匯入時呼叫Process(),那麼這將啟動無限繼承的新程式(或直到機器耗盡資源)。

這是隱藏對Process()內部呼叫的原,使用if __name__ == '__main__':,這個if語句中的語句將不會在匯入時被呼叫。

以上就是python process模組的使用簡介的詳細內容。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2774505/,如需轉載,請註明出處,否則將追究法律責任。

相關文章