multiprocessing.process的用法

multiprocessing模塊

仔細說來,multiprocess不是一個模塊而是python中一個操做、管理進程的包。 之因此叫multi是取自multiple的多功能的意思,在這個包中幾乎包含了和進程有關的全部子模塊。因爲提供的子模塊很是多,爲了方便你們歸類記憶,我將這部分大體分爲四個部分:建立進程部分,進程同步部分,進程池部分,進程之間數據共享。linux

multiprocessing.Process模塊

process模塊是一個建立進程的模塊,藉助這個模塊,就能夠完成進程的建立。windows

process模塊介紹

Process([group [, target [, name [, args [, kwargs]]]]]),由該類實例化獲得的對象,表示一個子進程中的任務(還沒有啓動)安全

強調:網絡

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

參數介紹:app

  • 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 的時候,就不會遞歸運行了。dom

Process的用法

1、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
主進程結束

2、查詢進程的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

4、判斷進程的生死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
主進程

5、殺死進程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
主進程

6、經過繼承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 正在和女主播聊天
主線程

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

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
相關文章
相關標籤/搜索