標籤:並發 元組 後台運行 live 網路 tpi inf pytho bsp
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(‘主‘)
終端列印:
Python 並發編程-進程