2018年5月19日筆記
阿新 • • 發佈:2018-05-21
共享內存 main 多核cpu 需要 target 創建 uil out lease
- 進程的概念
進程是程序在計算機上的一次執行活動。
進程可分為系統進程和用戶進程。
所有正在運行的進程輪流使用CPU,任何一個時間點有且只有一個進程占用CPU。
- 進程與線程的區別
進程 > 線程
多進程使用CPU的多個核,適合運算密集型
多線程使用CPU的一個核,核心IO密集型
- python多進程 —— muiltiprocessing模塊
python中的多線程無法利用多核優勢,如果想要充分地使用多核CPU的資源(os.cpu_count()查看),在python中大部分情況需要使用多進程。Python提供了multiprocessing。
Multiprocessing支持子進程、通信和共享數據、執行不同形式的同步,提供了Process、Queue、Pipe、Lock等組件。
- 創建一個Process實例
p1 = multiprocessing.Process(target=func, args=(2,))
target=函數名字
args=函數所需的參數,以tuple形式傳入,必須有逗號,註意單個參數的形式
multiprocessing的2個常用方法:
multiprocessing.cpu_count() # 1. 統計CPU總數 multiprocessing.active_children() # 2. 獲取所有子進程
- Process實例的常用屬性和方法
常用屬性:
p1 = multiprocessing.Process(target=func, args=(2,)) p1.name# 進程名字 p1.pid # 進程ID
常用方法:
p1 = multiprocessing.Process(target=func, args=(2,)) p1.is_alive() # 判斷進程是否存活 p1.run() # 啟動進程(不常用) p1.start() # 啟動進程,自動調用run()方法(常用) p1.join(timeout=5) # 等待進程結束或直到超時(5s)
- 習題1
1 import multiprocessing 2 import time 3 4 5 defworker(args, interval): 6 print("start worker {0}".format(args)) 7 time.sleep(interval) 8 print("end worker {0}".format(args)) 9 10 def main(): 11 print("start main") 12 p1 = multiprocessing.Process(target=worker, args=(1, 1)) 13 p2 = multiprocessing.Process(target=worker, args=(2, 2)) 14 p3 = multiprocessing.Process(target=worker, args=(3, 3)) 15 p1.start() 16 p2.start() 17 p3.start() 18 print("end main") 19 20 if __name__ == ‘__main__‘: 21 main()
start main end main start worker 1 start worker 2 start worker 3 end worker 1 end worker 2 end worker 3
- 習題2
1 import multiprocessing 2 import time 3 4 def worker(args, interval): 5 print("start worker {0}".format(args)) 6 time.sleep(interval) 7 print("end worker {0}".format(args)) 8 9 def main(): 10 print("start main") 11 p1 = multiprocessing.Process(target=worker, args=(1, 1)) 12 p2 = multiprocessing.Process(target=worker, args=(2, 2)) 13 p3 = multiprocessing.Process(target=worker, args=(3, 3)) 14 p1.start() 15 p1.join(timeout=0.5) 16 p2.start() 17 p3.start() 18 print("the number of CPU is: {0}".format(multiprocessing.cpu_count())) 19 for p in multiprocessing.active_children(): 20 print("The name of active children is: {0}, pid is: {1} is alive".format(p.name, p.pid)) 21 print("end main") 22 23 if __name__ == ‘__main__‘: 24 main()
start main start worker 1 the number of CPU is: 4 The name of active children is: Process-1, pid is: 1348 is alive The name of active children is: Process-3, pid is: 1350 is alive The name of active children is: Process-2, pid is: 1349 is alive end main start worker 2 start worker 3 end worker 1 end worker 2 end worker 3
- Lock組件
使用多進程來讀寫文件時,讀和寫不能同時進行,為了這種多個進程共享同一資源的場景不出問題,引入了鎖機制。
鎖有兩種狀態:被鎖(locked)和沒有被鎖(unlocked)。擁有acquire()和release()兩種方法,並且遵循一下的規則:
- 如果一個鎖的狀態是unlocked,調用acquire()方法改變它的狀態為locked
- 如果一個鎖的狀態是locked,acquire()方法將會阻塞,直到另一個線程調用release()方法釋放了鎖;
- 如果一個鎖的狀態是unlocked調用release()會拋出RuntimeError異常;
- 如果一個鎖的狀態是locked,調用release()方法改變它的狀態為unlocked。
- 習題3
1 import multiprocessing 2 import time 3 4 def add1(lock, value, number): 5 with lock: 6 print("start add1 number= {0}".format(number)) 7 for i in range(1, 5): 8 number += value 9 time.sleep(0.3) 10 print("number = {0}".format(number)) 11 12 def add3(lock, value, number): 13 lock.acquire() 14 print("start add3 number= {0}".format(number)) 15 try: 16 for i in range(1, 5): 17 number += value 18 time.sleep(0.3) 19 print("number = {0}".format(number)) 20 except Exception as e: 21 raise e 22 finally: 23 lock.release() 24 pass 25 26 if __name__ == ‘__main__‘: 27 print("start main") 28 number = 0 29 lock = multiprocessing.Lock() 30 p1 = multiprocessing.Process(target=add1, args=(lock, 1, number)) 31 p3 = multiprocessing.Process(target=add3, args=(lock, 3, number)) 32 p1.start() 33 p3.start() 34 print("end main")
start main end main start add1 number= 0 number = 1 number = 2 number = 3 number = 4 start add3 number= 0 number = 3 number = 6 number = 9 number = 12
- 多進程間可共享內存
multiprocessing模塊提供了共享內存的操作。
一般的變量在進程之間是無法通信的,multiprocessing提供了Value和Array模塊,實現了進程間的數據共享。
Python中還提供了強大的Manager模塊專門來做數據共享,其支持的類型非常多,包括Value, Array, list, dict, Queue, Lock等。
- 習題4
1 import multiprocessing 2 from multiprocessing import Value, Array, Manager 3 import time 4 5 6 def add1(value, number): 7 print("start add1 number= {0}".format(number.value)) 8 for i in range(1, 5): 9 number.value += value 10 print("number = {0}".format(number.value)) 11 12 def add3(value, number): 13 print("start add3 number= {0}".format(number.value)) 14 try: 15 for i in range(1, 5): 16 number.value += value 17 print("number = {0}".format(number.value)) 18 except Exception as e: 19 raise e 20 21 if __name__ == ‘__main__‘: 22 print("start main") 23 number = Value(‘d‘, 0) 24 p1 = multiprocessing.Process(target=add1, args=(1, number)) 25 p3 = multiprocessing.Process(target=add3, args=(3, number)) 26 p1.start() 27 p3.start() 28 print("end main")
start main end main start add1 number= 0.0 number = 1.0 number = 2.0 number = 3.0 number = 4.0 start add3 number= 4.0 number = 7.0 number = 10.0 number = 13.0 number = 16.0
2018年5月19日筆記