目錄前端
1.建立進程的兩種方式: 函數, 類. 2.pid: os.getpid() os.getppid() tasklist tasklist| findstr 進程名 3.進程與進程之間是有物理隔離: 不能共享內存的數據.(lock,隊列) 4.join阻塞: 讓主進程等待子進程結束以後,在執行. 5.其餘屬性: terminate() is_alive() name, 6.守護進程: 將子進程設置成守護進程,當主進程結束了,子進程就立刻結束.
殭屍進程:一個進程使用fork建立子進程,若是子進程退出,而父進程並無調用wait或waitpid獲取子進程的狀態信息,那麼子進程的進程描述符仍然保存在系統中,這種進程稱之爲殭屍進程. #基於unix環境(linux,macOS) #主進程須要等待子進程結束以後,主進程才結束 主進程時刻監測子進程的運行狀態,當子進程結束以後,一段時間以內,將子進程進行回收. #爲何主進程不在子進程結束後立刻對其回收呢? # 1. 主進程與子進程是異步關係.主進程沒法立刻捕獲子進程何時結束. # 2. 若是子進程結束以後立刻再內存中釋放資源,主進程就沒有辦法監測子進程的狀態了. #unix針對於上面的問題,提供了一個機制. #全部的子進程結束以後,立馬會釋放掉文件的操做連接,內存的大部分數據,可是會保留一些內容: 進程號,結束時間,運行狀態,等待主進程監測,回收. 殭屍進程: 全部的子進程結束以後,在被主進程回收以前,都會進入殭屍進程狀態. #殭屍進程有無危害??? #若是父進程不對殭屍進程進行回收(wait/waitpid),產生大量的殭屍進程,這樣就會佔用內存,佔用進程pid號.
#父進程因爲某種緣由結束了,可是你的子進程還在運行中,這樣你的這些子進程就成了孤兒進程.你的父進程若是結束了,你的全部的孤兒進程就會被init進程的回收,init就變成了你的父進程,對你進行回收.
#父進程產生了大量子進程,可是不回收,這樣就會造成大量的殭屍進程,解決方式就是直接殺死父進程,將全部的殭屍進程變成孤兒進程進程,由init進行回收.
# 三個同事 同時用一個打印機打印內容. # 三個進程模擬三個同事, 輸出平臺模擬打印機. # 版本一: # from multiprocessing import Process # import time # import random # import os # # def task1(): # print(f'{os.getpid()}開始打印了') # time.sleep(random.randint(1,3)) # print(f'{os.getpid()}打印結束了') # # def task2(): # print(f'{os.getpid()}開始打印了') # time.sleep(random.randint(1,3)) # print(f'{os.getpid()}打印結束了') # # def task3(): # print(f'{os.getpid()}開始打印了') # time.sleep(random.randint(1,3)) # print(f'{os.getpid()}打印結束了') # # if __name__ == '__main__': # # p1 = Process(target=task1) # p2 = Process(target=task2) # p3 = Process(target=task3) # # p1.start() # p2.start() # p3.start() # 如今是全部的進程都併發的搶佔打印機, # 併發是以效率優先的,可是目前咱們的需求: 順序優先. # 多個進程共強一個資源時, 要保證順序優先: 串行,一個一個來. # 版本二: # from multiprocessing import Process # import time # import random # import os # # def task1(p): # print(f'{p}開始打印了') # time.sleep(random.randint(1,3)) # print(f'{p}打印結束了') # # def task2(p): # print(f'{p}開始打印了') # time.sleep(random.randint(1,3)) # print(f'{p}打印結束了') # # def task3(p): # print(f'{p}開始打印了') # time.sleep(random.randint(1,3)) # print(f'{p}打印結束了') # # if __name__ == '__main__': # # p1 = Process(target=task1,args=('p1',)) # p2 = Process(target=task2,args=('p2',)) # p3 = Process(target=task3,args=('p3',)) # # p2.start() # p2.join() # p1.start() # p1.join() # p3.start() # p3.join() # 咱們利用join 解決串行的問題,保證了順序優先,可是這個誰先誰後是固定的. # 這樣不合理. 你在爭搶同一個資源的時候,應該是先到先得,保證公平. # 版本3: from multiprocessing import Process from multiprocessing import Lock import time import random import os def task1(p,lock): ''' 一把鎖不能連續鎖兩次 lock.acquire() lock.acquire() lock.release() lock.release() ''' lock.acquire() print(f'{p}開始打印了') time.sleep(random.randint(1,3)) print(f'{p}打印結束了') lock.release() def task2(p,lock): lock.acquire() print(f'{p}開始打印了') time.sleep(random.randint(1,3)) print(f'{p}打印結束了') lock.release() def task3(p,lock): lock.acquire() print(f'{p}開始打印了') time.sleep(random.randint(1,3)) print(f'{p}打印結束了') lock.release() if __name__ == '__main__': mutex = Lock() p1 = Process(target=task1,args=('p1',mutex)) p2 = Process(target=task2,args=('p2',mutex)) p3 = Process(target=task3,args=('p3',mutex)) p2.start() p1.start() p3.start()
#共同點: 均可以把併發變成串行, 保證了順序. #不一樣點: join人爲設定順序,lock讓其爭搶順序,保證了公平性.
# 搶票系統. # 1. 先能夠查票.查詢餘票數. 併發 # 2. 進行購買,向服務端發送請求,服務端接收請求,在後端將票數-1,返回到前端. 串行. # from multiprocessing import Process # import json # import time # import os # import random # # # def search(): # time.sleep(random.randint(1,3)) # 模擬網絡延遲(查詢環節) # with open('ticket.json',encoding='utf-8') as f1: # dic = json.load(f1) # print(f'{os.getpid()} 查看了票數,剩餘{dic["count"]}') # # # def paid(): # with open('ticket.json', encoding='utf-8') as f1: # dic = json.load(f1) # if dic['count'] > 0: # dic['count'] -= 1 # time.sleep(random.randint(1,3)) # 模擬網絡延遲(購買環節) # with open('ticket.json', encoding='utf-8',mode='w') as f1: # json.dump(dic,f1) # print(f'{os.getpid()} 購買成功') # # def task(): # search() # paid() # # # if __name__ == '__main__': # # for i in range(6): # p = Process(target=task) # p.start() # 當多個進程共強一個數據時,若是要保證數據的安全,必需要串行. # 要想讓購買環節進行串行,咱們必需要加鎖處理. # # from multiprocessing import Process # from multiprocessing import Lock # import json # import time # import os # import random # # # def search(): # time.sleep(random.randint(1,3)) # 模擬網絡延遲(查詢環節) # with open('ticket.json',encoding='utf-8') as f1: # dic = json.load(f1) # print(f'{os.getpid()} 查看了票數,剩餘{dic["count"]}') # # # def paid(): # with open('ticket.json', encoding='utf-8') as f1: # # dic = json.load(f1) # if dic['count'] > 0: # dic['count'] -= 1 # time.sleep(random.randint(1,3)) # 模擬網絡延遲(購買環節) # with open('ticket.json', encoding='utf-8',mode='w') as f1: # json.dump(dic,f1) # print(f'{os.getpid()} 購買成功') # # # def task(lock): # search() # lock.acquire() # paid() # lock.release() # # if __name__ == '__main__': # mutex = Lock() # for i in range(6): # p = Process(target=task,args=(mutex,)) # p.start() # 當不少進程搶一個資源(數據)時, 你要保證順序(數據的安全),必定要串行. # 互斥鎖: 能夠公平性的保證順序以及數據的安全. # 基於文件的進程之間的通訊: # 效率低. # 本身加鎖麻煩並且很容易出現死鎖.
隊列: 把隊列理解成一個容器,這個容器能夠承載一些數據, 隊列的特性: 先進先出永遠保持這個數據. FIFO(first in first out). # from multiprocessing import Queue # q = Queue() # def func(): # print('in func') # q.put(1) # q.put('alex') # q.put([1,2,3]) # q.put(func) # # # print(q.get()) # print(q.get()) # print(q.get()) # f = q.get() # f() # from multiprocessing import Queue # q = Queue(3) # # q.put(1) # q.put('alex') # q.put([1,2,3]) # # q.put(5555) # 當隊列滿了時,在進程put數據就會阻塞. # # q.get() # # print(q.get()) # print(q.get()) # print(q.get()) # print(q.get()) # 當數據取完時,在進程get數據也會出現阻塞,直到某一個進程put數據. # from multiprocessing import Queue # q = Queue(3) # maxsize # # q.put(1) # q.put('alex') # q.put([1,2,3]) # q.put(5555,block=False) # # print(q.get()) # print(q.get()) # print(q.get()) # print(q.get(timeout=3)) # 阻塞3秒,3秒以後還阻塞直接報錯. # print(q.get(block=False)) # block=False 只要遇到阻塞就會報錯.