Python程序中的進程操作-開啟多進程


Python程序中的進程操作-開啟多進程

之前我們已經了解了很多進程相關的理論知識,了解進程是什么應該不再困難了,剛剛我們已經了解了,運行中的程序就是一個進程。所有的進程都是通過它的父進程來創建的。因此,運行起來的python程序也是一個進程,那么我們也可以在程序中再創建進程。多個進程可以實現並發效果,也就是說,當我們的程序中存在多個進程的時候,在某些時候,就會讓程序的執行速度變快。以我們之前所學的知識,並不能實現創建進程這個功能,所以我們就需要借助python中強大的模塊。

一、mulitprocess模塊

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

二、mulitprocess.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為子進程的名稱

3.1方法介紹

  • 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模塊創建進程

在一個python進程中開啟子進程,start方法和並發效果。

4.1在Python中啟動的第一個子進程

import time
from multiprocessing import Process

def f(name):
    print('hello', name)
    print('我是子進程')

if __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()
    time.sleep(1)
    print('執行主進程的內容了')

4.2join方法

import time
from multiprocessing import Process

def f(name):
    print('hello', name)
    time.sleep(1)
    print('我是子進程')


if __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()
    # p.join()
    print('我是父進程')

4.3查看主進程和子進程的進程號

import os
from multiprocessing import Process

def f(x):
    print('子進程id :',os.getpid(),'父進程id :',os.getppid())
    return x*x

if __name__ == '__main__':
    print('主進程id :', os.getpid())
    p_lst = []
    for i in range(5):
        p = Process(target=f, args=(i,))
        p.start()

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

4.4多個進程同時運行

import time
from multiprocessing import Process


def f(name):
    print('hello', name)
    time.sleep(1)


if __name__ == '__main__':
    p_lst = []
    for i in range(5):
        p = Process(target=f, args=('bob',))
        p.start()
        p_lst.append(p)

4.5多個進程同時運行,再談join方法(1)

import time
from multiprocessing import Process


def f(name):
    print('hello', name)
    time.sleep(1)


if __name__ == '__main__':
    p_lst = []
    for i in range(5):
        p = Process(target=f, args=('bob',))
        p.start()
        p_lst.append(p)
        p.join()
    # [p.join() for p in p_lst]
    print('父進程在執行')

4.6多個進程同時運行,再談join方法(2)

import time
from multiprocessing import Process

def f(name):
    print('hello', name)
    time.sleep(1)

if __name__ == '__main__':
    p_lst = []
    for i in range(5):
        p = Process(target=f, args=('bob',))
        p.start()
        p_lst.append(p)
    # [p.join() for p in p_lst]
    print('父進程在執行')

除了上面這些開啟進程的方法,還有一種以繼承Process類的形式開啟進程的方式

4.7通過繼承Process累開啟進程

import os
from multiprocessing import Process


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

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('主線程')

進程之間的數據隔離問題


免責聲明!

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



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