一 .程序中的進程操做python
仔細說來,multiprocess不是一個模塊而是python中一個操做、管理進程的包。 之因此叫multi是取自multiple的多功能的意思,在這個包中幾乎包含了和進程有關
的全部子模塊。因爲提供的子模塊很是多,爲了方便你們歸類記憶,我將這部分大體分爲四個部分:建立進程部分,進程同步部分,進程池部分,進程之間數據共享。
process模塊是一個建立進程的模塊,藉助這個模塊,就能夠完成進程的建立。linux
2. 進程(參數 方法 屬性 注意事項)編程
參數說明 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開啓的進程 屬性介紹 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字符的字符串。這個鍵的用途是爲涉及網絡鏈接的底層進程間通訊提供安全性,這類鏈接只有在具備相同的身份驗證鍵時
才能成功(瞭解便可)
在windows中使用process模塊的注意事項 在Windows操做系統中因爲沒有fork(linux操做系統中建立進程的機制),在建立子進程的時候會自動 import 啓動它的這個文件,而在 import
的時候又執行了整個文件。所以若是將process()直接寫在文件中就會無限遞歸建立子進程報錯。因此必須把建立子進程的部分使用if __name__ ==‘__main__’
判斷保護起來,import 的時候 ,
就不會遞歸運行了。
3. 進程建立使用windows
from multiprocessing import Process def run(): print("22222") if __name__=="__main__": p=Process(target=run) # 實例化進程 p.start() print("*******************************************") # 進程傳參數 def run(*args): print(args) if __name__=="__main__": p=Process(target=run,args=(10,20,30)) # 實例化進程 p.start() print("*******************************************") # 來查看進程直間的關係 os.getpid() 查看當前進程號 os.getppid() 查看當前父進程號 def run(*args): print(args) time.sleep(1) print(1111111111111111111111111111) print(os.getpid(),"查看當前子進程號3") # 1748 # os.getpid() 查看當前進程號 print(os.getppid(),"查看父進程號4") # 10120 os.getppid() 查看當前父進程號 if __name__ == "__main__": p1 = Process(target=run, args=(10, 20, 30)) # 實例化進程 p1.start() print("我是主進程。。。。。") print(os.getpid(),"查看當前主進程號1") #10120 # os.getpid() 查看當前進程號 print(os.getppid(),"查看當前執行父進程號2") # 7372 # os.getppid() 查看當前父進程號 print(p1.name) # Process-1 print("*******************************************") # 多進程 """multiprocessing 庫 是一個跨平臺版本多進程模塊 提供了一個Process類來表明一個進程對象 """ from multiprocessing import Process from time import sleep import os # 子進程須要執行代碼 def run(str): print("子進程啓動了") sleep(3) print("子進程結束") if __name__ == "__main__": print("main是主(父)進程啓動....") # 01 建立進程 子進程 p=Process(target=run,args =("nice",)) # target 說明進程執行的指定代碼(函數) # 02 啓動進程 # 父進程的結束不能影響子進程 讓父進程等待子進程結束在執行父進程 p.start() print("父進程結束....") sleep(2) # 執行順序 # main是主(父)進程啓動.... # 父進程結束.... # 子進程啓動了 # 子進程結束
4. 多進程啓動(for循環 join進程感知)安全
def run(*args): print(args) if __name__=="__main__": p1=Process(target=run,args=(10,20,30)) # 實例化進程 p1.start() p2= Process(target=run, args=(555,666,777)) p2.start() print("我是主進程") print("***********************************************") def run(*args): print(args) if __name__ == "__main__": for i in range(5): p1 = Process(target=run, args=(10, 20, 30)) # 實例化進程 p1.start()
print("***********************************************")
進程方法應用join 感知進程結束 至關於異步程序 改成同步程序 def run(*args): print(args) print("我是子進程2222222222222") time.sleep(2) print("我是子進程333333333333") if __name__ == "__main__": p1 = Process(target=run, args=(10, 20, 30)) # 實例化進程 p1.start() p1.join() # 應用join 感知進程結束 至關於異步程序 改成同步程序 有一個阻塞效果 就是子進程結束完了才執行主進程 print("我是主進程111111111111")
print("***********************************************")
join 進程方法應用感知 def run(): print("我是子進程2222222222222") time.sleep(2) # 在這休息兩秒 可是程序沒有停下 在休息2秒的過程當中 他在執行上面打印4次 就沒有等 在執行下面打印4次 print("我是子進程333333333333") if __name__ == "__main__": ret=[] for i in range(4): p1 = Process(target=run,) # 實例化進程 ret.append(p1) p1.start() for p in ret: p.join() #等待 上面因此進程必須執行完了才能執行下面代碼 在join以前是異步執行 當遇到join有個阻塞效果就變成同步執行 print("完成了哈哈哈.......") # 就至關於在join以前 開闢了四條跑道 這四個進程在各自的跑道跑 可是這四個進程有跑的慢的和跑的快的(意思就是每一個進程速度不同) # 當遇到join 跑的快的進程要等跑的慢的進程(意思就是四個進程都跑完) 在計算成績各自跑的成績 就變成了同步
print("***********************************************")
join(進程方法應用join 感知進程結束 至關於異步程序 改成同步程序)
def run(filename,coon): with open(filename,"w") as f1: f1.write(coon*10*'*') if __name__ == "__main__": ret=[] for i in range(4): p1 = Process(target=run,args=("info%s"%i,i)) # 實例化進程 ret.append(p1) p1.start() print(ret) for p in ret:p.join() # 等待上面寫完了在向用戶展現因此寫的文件 # 有個阻塞等待效果 join以前是異步寫入 遇到join變同步寫入完了 才能執行下面代碼 print([i for i in os.walk(r"H:\python之路2\day1")]) # # 同步0.1=400 =40 # 異步 400 0.1 =0.1
print("***********************************************")
通個類繼承來實現開啓多個進程
class MyProcess(Process): def __init__(self,a,b): super().__init__() # 繼承Proceess self.a=a self.b=b def run(self): print(self.a) print(self.b) print(self.pid) if __name__=="__main__": p1=MyProcess(1,2) p1.start() #至關於 # p2.run() 只是內部做爲處理的 p2 = MyProcess(555, 99999) p2.start() # 至關於 # p2.run() 只是內部做爲處理的 p1.join() p2.join() print("我是主進程!!!!!!!!!!!!!!1")
print("**********************************************************")
進程池概念 Pool
import os,time,random from multiprocessing import Pool # 多進程就用Pool (進程池) def run(name): print("子進程啓動22222",name,getpid()) print("子進程程結束2222",name,getpid()) if __name__ == '__main__': print("父進程啓動11111") # 01 建立多個進程 # 進程池 # 表示能夠同時執行進程數量 # Pool默認大小是cpu核心數 pp=Pool(2) for i in range(5): # 02 建立進程 放入進程池統一管理 pp.apply_async(run,args=(i,)) #apply 阻塞 同步方法 # apply_async 阻塞 異步方法 # 注意:在調用join以前必須先調用close 調用close以後就不能再繼續添加新的進程了 pp.close() #注意: 是進程池對象調用join會等待進程池中全部的子進程結束完畢再去執行父進程 pp.join() print("父進程結束11111")
# 多進程 """multiprocessing 庫 是一個跨平臺版本多進程模塊 提供了一個Process類來表明一個進程對象 """ from multiprocessing import Pool # 使用多進程 import os ,time ,random def run(name): print("子進程啓動--%s"%(name,os.getpid())) # print(name,os.getpid()) start=time.time() time.sleep(random.choiec([1,2,3])) end=time.time() print("子進程%d結束--%s--耗時%2.f"%(name,os.getpid(),end-start)) # print(name,os.getpid(),end-start) # if __name__=="__main__": print("父進程啓動......................") # 01建立多進程 # 進程池 # Pool() 默認是大小cpu核心數 pp=Pool(2) #表示能夠同時執行的進程數量 for i in range(3): # 建立3個進程 # 建立進程,放入進程池統一管理 pp.apply_async(run,args=(i,)) # 在調用join以前必須先調用close調用close以後就不能再繼續添加新的進程了 pp.close() # 進程池對象調用join 會等待進程池中全部的子進程結束完畢再去執行父進程 pp.join() print("父進程結束......................")
5. 進程之間數據隔離網絡
n=20 def run(): global n n = 60 print(n) # 60 run() print(n) # 60 print("*********************************************") num=100 # 說明子進程和父進程用的num是徹底不一樣的 是兩個徹底不一樣的變量 def run(): print("子進程開始") global num #global 表示使用全局變量 num+=1 print(num) print("子進程結束") if __name__=="__main__": print("父進程開始") p=Process(target=run) p.start() p.join() print("父進程結束---",num) # 在子進程中修改全局變量對父進程中的全局變量沒有影響 # 在建立子進程時對全局變量作了個備份 # 在父進程和子進程中的num是兩個徹底不一樣的變量 # 執行順序 # 父進程開始 # 子進程開始 # 101 # 子進程結束 # 父進程結束--- 100 print("*********************************************") def run(): global n n=1000 print("子進程",os.getpid(), n) # 子進程 8016 1000 if __name__ == "__main__": n = 600 p1 = Process(target=run) # 實例化進程 p1.start() p1.join() # 阻塞等待子進程結束後才執行主進程 print("主進程",os.getpid(),n) # 主進程 5244 600 print("*********************************************") def work(): global n n=222 print('子進程內: ',n) # 子進程內: 222 if __name__ == '__main__': n = 100 p=Process(target=work) p.start() print('主進程內: ',n) # 主進程內: 100
6. 進程實現網絡編程(注意子進程中不能加input)app
server from socket import * from multiprocessing import Process server=socket(AF_INET,SOCK_STREAM) server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) server.bind(('127.0.0.1',8080)) server.listen(5) def run(conn,addr): print(addr) while True: msg=conn.recv(1024) conn.send(msg.upper()) if __name__ == '__main__': while True: conn,addr=server.accept() p=Process(target=run,args=(conn,addr)) p.start() print("*******************************************") client from socket import * client=socket(AF_INET,SOCK_STREAM) client.connect(('127.0.0.1',8080)) while True: msg=input('請輸入字母: ').strip() client.send(msg.encode('utf-8')) msg=client.recv(1024) print(msg.decode('utf-8'))
7. 守護進程dom
會隨着主進程的結束而結束。
主進程建立守護進程
其一:守護進程會在主進程代碼執行結束後就終止
其二:守護進程內沒法再開啓子進程,不然拋出異常
注意:進程之間是互相獨立的,主進程代碼運行結束,守護進程隨即終止。
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) if __name__=="__main__": p = Myprocess('張三') p.daemon = True # 必定要在p.start()前設置,設置p爲守護進程,禁止p建立子進程,而且父進程代碼執行結束,p即終止運行 p.start() time.sleep(2) # 在sleep時查看進程id對應的進程ps -ef|grep id print('主進程') print("******************************************************") def run1(): while True: time.sleep( 0.2) print("我還活起的!!!!!!!!") if __name__=="__main__": p1=Process(target=run1) p1.daemon = True # 設置守護進程 (主進程代碼執行結束 子進程代碼也會天然而然結束 ) p1.start() # 隨着主進程代碼結束完畢 的結束 而結束 print(p1.is_alive()) # 判斷進程是否或着 i=0 while i<5: print("我是主進程1111111111111111111") time.sleep(2) i+=1 print(p1.is_alive()) # 判斷進程是否或着 print("******************************************************") 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) if __name__=="__main__": p1.daemon=True p1.start() p2.start() time.sleep(0.1) print("main-------") # 打印該行則主進程代碼結束,則守護進程p1應該被終止.#可能會有p1任務 # 執行的打印信息123,由於主進程打印main----時,p1也執行了,可是隨即被終止. # main - ------ # 456 # end45
8. 進程方法is_alive() and terminate()異步
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(2) print('%s還在和網紅臉聊天' %self.name) if __name__ == '__main__': p1=Myprocess('順悟空') p1.start() p1.terminate()# 結束一個子進程 關閉進程,不會當即關閉,因此is_alive馬上查看的結果可能仍是存活 print(p1.is_alive()) #結果爲True 檢查進程狀態 是否活着 print('開始') print(p1.is_alive()) #結果爲False print("我是主進程哈哈哈哈哈") # p1.terminate() 在主進程中結束一個子進程 結束一個子進程不是執行了立馬生效 須要一個操做系統響應的過程