三、守護進程(**) 主進程建立守護進程 其一:守護進程會在主進程代碼執行結束後就終止 其二:守護進程內沒法再開啓子進程,不然拋出異常: AssertionError: daemonic processes are not allowed to have children 注意:進程之間是互相獨立的,主進程代碼運行結束,守護進程隨即終止 A進程守護B進程 B進程結束 A也結束 若是父進程將子進程設置爲守護進程,那麼在主進程代碼運行完畢後守護進程就當即被回收 (好比 妃子守護皇帝 皇帝若是死了 妃子也就跟着陪葬了) 用法: 在主進程的對象後加入obj.daemon = True四、互斥鎖(**)(搶票代碼) 進程之間數據不共享,可是共享同一套文件系統, 因此訪問同一個文件,或同一個打印終端,是沒有問題的, 而共享帶來的是競爭,競爭帶來的結果就是錯亂,如何控制,就是加鎖處理 鎖本質上就是一個bool類型的標識符 多個進程在執行任務以前先判斷標識符 互斥鎖 兩個進程相互排斥 (好比 在宿舍你們公用一個廁所 一個使用中 其餘人不能用) 鎖的原理 就是加上一堆判斷 鎖至關於一個標記 爲何使用鎖,用來解決什麼問題? 當多個進程對統一資源進行讀寫時 引起了數據錯亂 解決方案就是變成串行,犧牲了效率而保證了數據安全 只有在多個任務修改共享的數據的時候纔會考慮用互斥鎖 互斥鎖與join的區別: 1.join 把整個進程變成串行 而且順序是人爲指定的 2.鎖Lock 能夠指定局部哪些代碼變成串行 而且對資源的競爭是公平的.一我的拿到鎖,其他人都等待 本質上就是一個標識符 True 或 False 多個進程要保證使用同一把鎖 如何使用? from multiprocessing import Lock mutex=Lock() 進程參數和任務函數的參數中傳入lock 在須要加鎖的地方 lock.acquire() 表示鎖定 在代碼執行完後 必定要lock.release() 表示釋放鎖 強調: 一、必定要在操做完畢後釋放鎖 二、互斥鎖lock.acquire()不能連續執行 (同一線程不能屢次acquire 會卡死) 注意 要想鎖住資源必須保證 你們拿到鎖是同一把 問題? 多個進程同時讀寫同一份數據時 可能形成數據混亂 (本地IO速度很快 基本不會出現問題) read讀數據麼有必要加鎖 write寫數據必須加總結: #加鎖能夠保證多個進程修改同一塊數據時,同一時間只能有一個任務能夠進行修改, 即串行的修改,沒錯,速度是慢了,但犧牲了速度卻保證了數據安全。 雖然能夠用文件共享數據實現進程間通訊,但問題是: 1.效率低(共享數據基於文件,而文件是硬盤上的數據) 2.須要本身加鎖處理 #所以咱們最好找尋一種解決方案可以兼顧: 一、效率高(多個進程共享一塊內存的數據) 二、幫咱們處理好鎖問題。 這就是mutiprocessing模塊爲咱們提供的基於消息的IPC通訊機制:隊列和管道。 1 隊列和管道都是將數據存放於內存中 2 隊列又是基於(管道+鎖)實現的,可讓咱們從複雜的鎖問題中解脫出來, 咱們應該儘可能避免使用共享數據,儘量使用消息傳遞和隊列, 避免處理複雜的同步和鎖問題,並且在進程數目增多時,每每能夠得到更好的可獲展性。五、進程間通信IPC機制:隊列,管道(*) 爲何使用IPC? 因爲進程之間內存是物理隔離的 沒法直接交互數據 實現方法 1.共享文件 速度慢,沒有鎖 2.管道PIPE 只能單向傳輸 必須有父子關係 沒有鎖 (不推薦使用,瞭解便可) !!!3.共享內存 存放共享數據,容量較小 速度快 Manage沒有鎖 Queue有鎖(先進先出) (用一塊內存區域做爲共享的內存區域) Manager 共享列表或字典 須要本身處理資源競爭 Queue 隊列 帶有阻塞效果 不用本身處理資源競爭 先進先出 例如自動扶梯 排隊買票六、進程隊列Queue=管道+鎖 (***)(推薦使用)進程彼此之間互相隔離,要實現進程間通訊(IPC),multiprocessing模塊支持兩種形式:隊列和管道,這兩種方式都是使用消息傳遞的 強調: 一、隊列Queue用來存成進程之間溝通的消息,數據量不該該過大 二、maxsize的值超過的內存限制就變得毫無心義 from multiprocessing import Queue q = Queue(3) # Queue裏可填數量,3表示存放的數量 q.put("hello") print(q.get()) q.put("hello",block=False) #阻塞操做,阻塞時會報錯 q.put("hello",timeout=3) #若是放滿了 願意等3秒 若是3秒後還存不進去 就報錯