********在python程序中的進程操做******** 以前咱們已經瞭解了不少進程相關的理論知識,瞭解進程是什麼應該再也不困難了,剛剛咱們已經瞭解了, 運行中的程序就是一個進程。全部的進程都是經過它的父進程來建立的。所以,運行起來的python程序 也是一個進程,那麼咱們也能夠在程序中再建立進程。多個進程能夠實現併發效果,也就是說,當咱們的 程序中存在多個進程的時候,在某些時候,就會讓程序的執行速度變快。以咱們以前所學的知識,並不能 實現建立進程這個功能,因此咱們就須要藉助python中強大的模塊。 ****multiprocessing模塊**** 仔細說來,multiprocess不是一個模塊而是python中一個操做、管理進程的包。 之因此叫multi是 取自multiple的多功能的意思,在這個包中幾乎包含了和進程有關的全部子模塊。因爲提供的子模塊非 常多,爲了方便你們歸類記憶,我將這部分大體分爲四個部分:建立進程部分,進程同步部分,進程池 部分,進程之間數據共享。 #由該類實例化獲得的對象,表示一個子進程中的任務(還沒有啓動) class Process(object): def __init__(self, group=None, target=None, name=None, args=(), kwargs={}): self.name = '' self.daemon = False self.authkey = None self.exitcode = None self.ident = 0 self.pid = 0 self.sentinel = None def run(self): pass def start(self): pass def terminate(self): pass def join(self, timeout=None): pass def is_alive(self): return False PS: 1.須要使用關鍵字的方式來指定參數 2.args指定的我傳給target函數的位置參數,是一個元組形式,必須有逗號 參數介紹: 1.group參數未使用,值始終爲None 2.target表示調用的對象,即子進程要執行的任務 3.args表示調用對象的位置參數元組 4.kwargs表示調用對象的字典 5.name爲子進程的名稱 方法介紹: 1. p.start():啓動進程,並調用改進程中的p.run() 2. p.run():進程啓動時運行的方法,正是它去調用target指定的函數,咱們自定義類的類中必定要實現該方法 3. p.terminate():強制終止進程p,不會進行任何清理操做,若是p建立了子進程沒改子進程就成爲殭屍進程, 使用該方法須要特別當心這種狀況。若是p還保存了一個鎖,那麼也將不會被釋放,而致使死鎖。 4. p.is_alive():若是p仍然運行,返回True 5. p.join([timeout]):主線程等待p終止(強調:是主線程處於等待,而p是處於運行狀態)。timeout是可選 的超時時間,須要強調的是,p.join()只能join住start開啓的進程,而不能join住run開啓的進程。 屬性介紹 1. p.daemon:默認值爲False,若是設爲True,表明p爲後臺運行的守護進程,當p的父進程終止時,p也隨之終止。 而且設定爲True後,p不能建立本身的新進程,必須在p.start()以前設置。 2. p.name:進程的名稱 3. p.pid:進程的pid 4. p.exitcode:進程在運行時爲None,若是爲-N,表示被信號N結束了 5. p.authkey:進程的身份驗證鍵,默認是由os.urandom()隨機生成的32字符的字符串。這個鍵的用途是爲涉及網 絡鏈接的底層進程間通訊提供安全性,這類鏈接只有在具備相同的身份驗證鍵時才能成功 在Windows中使用process模塊的注意事項 在Windows操做系統中因爲沒有fork(linux操做系統中建立進程的機制),在建立子進程的時候會自動 import 啓 動它的這個文件,而在 import 的時候又執行了整個文件。所以若是將process()直接寫在文件中就會無限遞歸創 建子進程報錯。因此必須把建立子進程的部分使用if __name__ ==‘__main__’ 判斷保護起來,import 的時候 , 就不會遞歸運行了。 **使用Process模塊建立進程 方式一 from multiprocessing import Process import os import time def func(s): print(s) print('子進程pid:%s', os.getpid()) # 獲取進程id print('子進程ppid:%s', os.getppid()) # 獲取進程父親id if __name__ == '__main__': p = Process(target=func, args=('Tome',)) p.start() time.sleep(1) print('主進程pid:%s', os.getpid()) 方式二 from multiprocessing import Process class MyProcess(Process): def __init__(self, na): self.na = na super().__init__() # 必須繼承init 由於Process有一些屬性有本身的功能 def run(self): print('我是%s' % self.na) print('這裏是子進程!') if __name__ == '__main__': p = MyProcess('Tone') p.start() # 是指,解釋器告訴系統,去幫我開啓一個進程 就緒狀態 jion方法 from multiprocessing import Process import time def f(name): print('hello', name) time.sleep(1) print('我是子進程') if __name__ == '__main__': p = Process(target=f, args=('bob',)) p.start() # p.join() #感知一個子進程的結束,將異步變同步 print('我是父進程') 進程之間的數據隔離問題 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) 進階,多個進程同時運行(注意子進程的執行順序不是根據啓動順序決定的) **多個進程同時運行 方式一 import time from multiprocessing import Process def func(name): print('hello', name) time.sleep(1) if __name__ == '__main__': p_lst = [] for i in range(5): p = Process(target=func, args=('Tom',)) p.start() p_lst.append(p) 方式二 import time from multiprocessing import Process class MyProcess(Process): def __init__(self, na): super().__init__() self.na = na def run(self): print('hello', self.na) time.sleep(1) if __name__ == '__main__': p_lst = [] for i in range(5): p = MyProcess('Tom') p.start() p_lst.append(p) **多個進程同時運行,再談join方法(1) import time from multiprocessing import Process def func(name): print('hello', name) time.sleep(1) if __name__ == '__main__': p_lst = [] for i in range(5): p = Process(target=func, args=('Tom',)) p.start() p_lst.append(p) p.join() print('父進程在執行') **多個進程同時運行,在談join方法(2) import time from multiprocessing import Process def func(name): print('hello', name) time.sleep(1) if __name__ == '__main__': p_lst = [] for i in range(5): p = Process(target=func, args=('Tom',)) p.start() p_lst.append(p) [p.join() for p in p_lst] print('父進程在執行') ****守護進程**** 會隨着主進程的結束而結束。 主進程建立守護進程 其一:守護進程會在主進程代碼執行結束後就終止 其二:守護進程內沒法再開啓子進程,不然拋出異常:AssertionError: daemonic processes are not allowed to have children 注意:進程之間是互相獨立的,主進程代碼運行結束,守護進程隨即終止 例子: import os import time from multiprocessing import Process class Myprocess(Process): def __init__(self, person): super().__init__() self.person = person def run(self): print(os.getpid(), self.name) print('%s正在和女主播聊天' % self.person) p = Myprocess('Tom') p.daemon = True # 必定要在p.start()前設置,設置p爲守護進程,禁止p建立子進程,而且父進程代碼執行結束,p即終止運行 p.start() time.sleep(10) # 在sleep時查看進程id對應的進程ps -ef|grep id print('主進程') from multiprocessing import Process import time def foo(): print(123) time.sleep(1) print("end123") def bar(): print(456) time.sleep(3) print("end456") p1 = Process(target=foo) p2 = Process(target=bar) p1.daemon = True p1.start() p2.start() time.sleep(0.1) print("main-------") # 打印該行則主進程代碼結束,則守護進程p1應該被終止.#可能會有p1任務執行的打印信息123,由於主進程打印main----時,p1也執行了,可是隨即被終止. ****多進程中的其餘方法**** from multiprocessing import Process import time import random class Myprocess(Process): def __init__(self,person): self.name=person super().__init__() def run(self): print('%s正在和網紅臉聊天' %self.name) time.sleep(random.randrange(1,5)) print('%s還在和網紅臉聊天' %self.name) p1=Myprocess('Tom') p1.start() p1.terminate()#關閉進程,不會當即關閉,因此is_alive馬上查看的結果可能仍是存活 print(p1.is_alive()) #結果爲True print('開始') print(p1.is_alive()) #結果爲False