Process類參數介紹 group 參數未使用, 值始終為None target 表示調用對象, 即子進程要執行的任務 args 表示調用對象的位置參數元組, args=(1,2,'hades',) 是一個元組形式,必須有逗號 kwargs 表示調用對象的字典, kwargs={'name':'h ...
Process類參數介紹
group -------- 參數未使用, 值始終為None
target -------- 表示調用對象, 即子進程要執行的任務
args ---------- 表示調用對象的位置參數元組, args=(1,2,'hades',) 是一個元組形式,必須有逗號
kwargs ------- 表示調用對象的字典, kwargs={'name':'hades','age':18}
name --------- 為子進程的名稱
Process類方法介紹
p.start() ----------------- 啟動進程, 並調用該子進程中的p.run()
p.run() ------------------- 進程啟動時運行的方法, 正是它去調用target指定的函數, 自定義類的類中一定要實現該方法
p.terminate() ----------- 強制終止進程p, 不會進行任何清理操作, 如果p創建了子進程, 該子進程就成了僵屍進程, 使用該方法需要特別小心這種情況.
如果p還保存了一個鎖那麼也將不會被釋放, 進而導致死鎖
p.is_alive() -------------- 判斷進程是否存活, 如果p仍然運行, 返回True
p.join() ------------------- 主進程等待p子進程終止(是主進程處於等的狀態,而p子進程處於運行的狀態), 只能join住start開啟的進程, 不能join住run開啟的進程
Process類屬性介紹
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字元的字元串.
這個鍵的用途是為涉及網路連接的底層進程間通信提供安全性,這類連接只有在具有相同的身份驗證鍵時才能成功(瞭解知識點)
什麼是進程
使用進程是要實現併發效果
進程就是一個正在進行/運行的程式, 換言之, 進程指的是一個程式的運行過程
程式vs進程:
程式: 只是一堆代碼文件
進程: 程式運行的過程才是進程
串列: 一個任務完完整整地運行完畢, 再執行下一個任務, 按次序依次進行
判斷串列的概念:
串列看起來就是一個一個運行的: 對
一個一個的運行就是串列: 錯誤
併發(切換+保存狀態): 多個任務看起來是同時運行, 單核就可以實行併發
並行: 多個任務是真正意義上的同時運行, 只有多核才能實現並行
多道技術的產生背景: 就是想要在單核下實現併發
如何實現:
1. 空間上的復用: 將記憶體分為幾部分, 每個部分放入一個程式的數據, 這樣同一時間記憶體中就有了多道程式的數據, 為CPU在多個任務間切換做準備
2. 時間上的復用: 多個進程共用CPU的時間
關鍵點就是CPU在多個任務之間進行切換
有兩種情況下會發生切換:
1. 一個任務占用CPU時間過長(沒有遇到IO操作): 會降低效率
2. 一個任務在運行的過程中遇到IO操作: 可以提升效率
開啟子進程的方式1
1 from multiprocessing import Process 2 import time 3 4 5 def task(name): 6 print('%s is running' % name) 7 time.sleep(3) 8 print('%s is done' % name) 9 10 11 # 在windows系統上開啟子進程的操作必須放到該行代碼下 12 if __name__ == '__main__': 13 p = Process(target=task, args=('子進程',)) # Process(target=task,kwargs={'name':'子進程'}) # 14 p.start() # 僅僅只是向操作系統發送一個創造子進程的信號 15 print('主')
終端列印:
開啟子進程的方式2
1 from multiprocessing import Process 2 import time 3 4 5 class Myprocess(Process): 6 def __init__(self, name): 7 super().__init__() 8 self.name = name 9 10 def run(self): 11 print('%s is running' % self.name) 12 time.sleep(3) 13 print('%s is done' % self.name) 14 15 16 # 在windows系統上開啟子進程的操作必須放到該行代碼下 17 if __name__ == '__main__': 18 p = Myprocess('子進程') 19 p.start() # 僅僅只是向操作系統發送一個創造子進程的信號 20 p.join() 21 print('主')
終端列印:
join方法
1 from multiprocessing import Process 2 import time 3 4 5 def task(name, n): 6 print('%s is running' % name) 7 time.sleep(n) 8 print('%s is done' % name) 9 10 11 if __name__ == '__main__': 12 start = time.time() 13 p_l = [] 14 for i in range(1, 4): 15 p = Process(target=task, args=('子進程%s' % i, i)) 16 p_l.append(p) 17 p.start() 18 19 for p in p_l: 20 p.join() 21 stop = time.time() 22 print('主', (stop - start))
終端列印:
進程之間記憶體隔離
1 from multiprocessing import Process 2 3 n = 100 4 5 6 def task(): 7 global n 8 n = 0 9 10 11 if __name__ == '__main__': 12 p = Process(target=task, ) 13 p.start() 14 p.join() 15 print('主', n)
終端列印:
進程的PID
1 from multiprocessing import Process, current_process 2 import time, os 3 4 5 def task(): 6 print('子進程[%s] 父進程<%s>' % (os.getpid(), os.getppid())) 7 time.sleep(300) 8 9 10 if __name__ == '__main__': 11 p = Process(target=task) 12 p.start() 13 print('主', os.getpid(), os.getppid()) 14 time.sleep(1000)
終端列印:
進程對象其他相關的屬性或方法
p.name 更改子進程的名字
1 from multiprocessing import Process 2 import time, os 3 4 5 def task(): 6 print('%s is running' % os.getppid()) 7 time.sleep(300) 8 9 10 if __name__ == '__main__': 11 p = Process(target=task, name='子進程1') 12 p.start() 13 print(p.name) 14 print('主') 15 time.sleep(1000)
終端列印:
terminate與is_alive
p.terminate() 關閉進程
p.is_alive() 查看進程是否存活
1 from multiprocessing import Process 2 import time, os 3 4 5 def task(): 6 print('%s is running' % os.getppid()) 7 time.sleep(300) 8 9 10 if __name__ == '__main__': 11 p = Process(target=task, name='子進程1') 12 p.start() 13 p.terminate() 14 time.sleep(0.1) 15 print(p.is_alive()) 16 print('主')
終端列印: