multiprocessing.process的用法


multiprocessing模塊

仔細說來,multiprocess不是一個模塊而是python中一個操作、管理進程的包。 之所以叫multi是取自multiple的多功能的意思,在這個包中幾乎包含了和進程有關的所有子模塊。由於提供的子模塊非常多,為了方便大家歸類記憶,我將這部分大致分為四個部分:創建進程部分,進程同步部分,進程池部分,進程之間數據共享。

multiprocessing.Process模塊

process模塊是一個創建進程的模塊,借助這個模塊,就可以完成進程的創建。

process模塊介紹

Process([group [, target [, name [, args [, kwargs]]]]]),由該類實例化得到的對象,表示一個子進程中的任務(尚未啟動)

強調:

  1. 需要使用關鍵字的方式來指定參數
  2. args指定的為傳給target函數的位置參數,是一個元組形式,必須有逗號

參數介紹:

  • group參數未使用,值始終為None
  • target表示調用對象,即子進程要執行的任務
  • args表示調用對象的位置參數元組,args=(1,2,'egon',)
  • kwargs表示調用對象的字典,kwargs={'name':'egon','age':18}
  • name為子進程的名稱

方法介紹

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

3.2 屬性介紹

  • p.daemon:默認值為False,如果設為True,代表p為后台運行的守護進程,當p的父進程終止時,p也隨之終止,並且設定為True后,p不能創建自己的新進程,必須在p.start()之前設置
  • p.name:進程的名稱
  • p.pid:進程的pid
  • p.exitcode:進程在運行時為None、如果為–N,表示被信號N結束(了解即可)
  • p.authkey:進程的身份驗證鍵,默認是由os.urandom()隨機生成的32字符的字符串。這個鍵的用途是為涉及網絡連接的底層進程間通信提供安全性,這類連接只有在具有相同的身份驗證鍵時才能成功(了解即可)

3.3 在windows中使用process模塊的注意事項

在Windows操作系統中由於沒有fork(linux操作系統中創建進程的機制),在創建子進程的時候會自動 import 啟動它的這個文件,而在 import 的時候又執行了整個文件。因此如果將process()直接寫在文件中就會無限遞歸創建子進程報錯。所以必須把創建子進程的部分使用if __name__ =='__main__ 判斷保護起來,import 的時候,就不會遞歸運行了。

Process的用法

一、jion用法

內部會調用wait(),等待執行完畢,回收pid

1.1 jion用法1

from multiprocessing import Process

import time

def foo():
    print('process start')
    time.sleep(2)
    print('process end')

if __name__ == '__main__':
    p = Process(target=foo) #創建子進程
    p.start()#給操作系統發指令,開啟子進程
    time.sleep(5)
    p.join()#阻塞住主進程再等待子進程結束,然后再往下執行,(了解的是:內部會待用wait())
    print('主進程')


# 
process start
process end
主進程

1.2join用法2

from multiprocessing import Process
import time
def foo(x):
    print('Process start')
    time.sleep(x)
    print('Process end')
if __name__ == '__main__':
    p1 = Process(target=foo,args=(1,)) #進程傳參的固定模式
    p2 = Process(target=foo,args=(2,))
    p3 = Process(target=foo,args=(3,))
    start = time.time()
    p1.start()
    p2.start()
    p3.start()
    p1.join()
    p2.join()
    p3.join()
    end = time.time()
    print(end-start)
    print('主進程')
#進程是同時開啟的,不確定是哪一個先開啟,並且創建子進程需要時間,因此是3秒多
Process start
Process start
Process start
Process end
Process end
Process end
3.136319160461426
主進程

join用法2,優化

from multiprocessing import Process

import time
def foo(x):
    print(f'process{x},start')
    time.sleep(x)
    print(f'process{x},end')
if __name__ == '__main__':
    strart = time.time()
    p_list = []
    for i in range(1,4):
        p=Process(target=foo,args=(i,))
        p.start()
        p_list.append(p)
    print(p_list)
    for p in p_list:
        p.join()
    end = time.time()
    print(end-strart)
    print('主進程')
    
   # 
[<Process(Process-1, started)>, <Process(Process-2, started)>, <Process(Process-3, started)>]
process1,start
process2,start
process3,start
process1,end
process2,end
process3,end
3.1335043907165527
主進程

1.3 join用法3

from multiprocessing import Process
import time
def foo(x):
    print(f'process{x},start')
    time.sleep(x)
    print(f'process{x},end')

if __name__ == '__main__':
    p1 = Process(target=foo,args=(1,))
    p2 = Process(target=foo,args=(2,))
    p3 = Process(target=foo,args=(3,))
    start = time.time()
    p1.start()
    p1.join()
    p2.start()
    p2.join()
    p3.start()
    p3.join()
    end = time.time()
    print(end-start)
    print('主進程結束')
#由於每一個進程都是在執行完后才會執行下一個進程,因此,時間是多余6s,創建子進程空間是需要時間的
process1,start
process1,end
process2,start
process2,end
process3,start
process3,end
6.339004039764404
主進程結束

二、查詢進程的pid

進程的pid,相當於人的id身份證一樣

from multiprocessing import Process,current_process
import os
import time

def task():
    print('子進程 start')
    print('在子進程中查詢自己的pid>',current_process().pid)
    print('在子進程中查詢父進程的pid>',os.getppid())
    time.sleep(200)
    print('子進程end')
if __name__ == '__main__':
    p = Process(target=task)
    p.start()
    print('在主進程中查看子進程的pid>',p.pid)#一定要寫在start之后,在給操作系統發送開啟子進程之后
    print('主進程的pid>',os.getpid())
    print('主進程的父進程的pid>',os.getppid())
    print('主進程')
    
###
在主進程中查看子進程的pid> 11112
主進程的pid> 7320
主進程的父進程的pid> 2464
主進程
子進程 start
在子進程中查詢自己的pid> 11112
在子進程中查詢父進程的pid> 7320

三,查詢進程名name

from multiprocessing import Process,current_process
import time
def foo():
    print('process start')
    print('子進程的名字',current_process().name)
    time.sleep(2)
    print('process end')
if __name__ == '__main__':
    p = Process(target=foo)
    p2 = Process(target=foo)
    p3 = Process(target=foo,name='ocean')

    p.start()
    p2.start()
    p3.start()
    print(p.name)
    print(p2.name)
    print(p3.name)
    print('主進程')
################
Process-1
Process-2
ocean
主進程
process start
子進程的名字 Process-1
process start
子進程的名字 Process-2
process start
子進程的名字 ocean
process end
process end
process end

四、判斷進程的生死is_alive()

from multiprocessing import Process
import time
def foo():
    print('process start')
    time.sleep(2)
    print('process end')
if __name__ == '__main__':
    p = Process(target=foo)
    p.start()
    print(p.is_alive())#True,進程開啟,進程或者
    time.sleep(5)
    print(p.is_alive())#False 代碼運行完畢,進程死亡(系統判定,實際情況在具體分析)
    print('主進程')
    
    
##############
True
process start
process end
False
主進程

五、殺死進程terminate()

from multiprocessing import Process
import time
def foo():
    print('process start')
    time.sleep(10)
    print('process end')
if __name__ == '__main__':
    p = Process(target=foo)
    p.start()
    p.terminate()#給操作系統發送一個請求,殺死進程的請求
    print(p.is_alive())
    p.join()
    print(p.is_alive())
    print('主進程')
###############
True
False
主進程

六、通過繼承Process類開啟進程

import os
from multiprocessing import Process


class MyProcess(Process):
    def __init__(self,name):
        # super(MyProcess,self).__init__()
        super().__init__()
        self.name=name
    def run(self):
        print(os.getpid())
        print('%s 正在和女主播聊天' %self.name)
if __name__ == '__main__':

        p1=MyProcess('wupeiqi')
        p2=MyProcess('yuanhao')
        p3=MyProcess('nezha')

        p1.start() # start會自動調用run
        p2.start()
        # p2.run()
        p3.start()


        p1.join()
        p2.join()
        p3.join()

        print('主線程')
        
####################
1516
wupeiqi 正在和女主播聊天
4864
yuanhao 正在和女主播聊天
18228
nezha 正在和女主播聊天
主線程

七、進程間的數據隔離問題

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



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM