day32:進程
- 2020 年 8 月 17 日
- 筆記
- PythonS31-筆記, Python全棧31期-筆記
目錄
進程的基本概念
什麼是進程?
進程就是正在運行的程式,它是作業系統中,資源分配的最小單位
什麼是資源分配?
資源分配:分配的是cpu和記憶體等物理資源
Linux中幾個關於進程的指令
ps -aux 查看進程號
ps -aux | grep 2860 查看對應進程號的進程
kill -9 2860 殺死進程
pid和ppid
獲取當前進程id: os.getpid()
獲取當前進程的父進程id: os.getppid()
進程初體驗
1.進程的基本使用
在使用進程之前,需要調用Process: from multiprocessing import Process
# (1) 進程的基本使用 def func(): print("1.子進程id>>{},2父進程id>>{}".format(os.getpid(),os.getppid())) # 為了解決windows 和 linux 系統的兼容問題,下面這句話必須加上,否則報錯 if __name__ == "__main__": # 創建子進程,返回進程對象,執行func這個任務 p = Process(target=func) # 調用子進程 p.start()
2.創建帶有參數的進程
def func(n): for i in range(1,n+1): print("1.子進程id>>{},2父進程id>>{}".format(os.getpid(),os.getppid())) if __name__ == "__main__": n = 5 #創建子進程 p = Process(target=func,args=(n,)) #調用子進程 p.start() for i in range(1,n+1): print("*" * i)
執行結果如下圖所示
產生如上結果的原因:因為子進程分配資源需要時間,而主進程早已經分配好資源了,不需要這個時間。所以主進程的內容先列印,子進程的內容後列印
3.進程之間的數據彼此隔離
count = 10 def func(): global count count += 1 print("我是子進程count={}".format(count)) if __name__ == "__main__": p=Process(target=func) p.start() time.sleep(1) print(count)
執行結果如下圖所示
產生如上結果的原因:如下圖所示,黃色部分都是子進程中的內容,子進程中有+1操作,所以子進程中的count肯定為11
但是主進程並沒有任何操作,只是單純的列印了一下count,所以主進程中的count為10
4.多個進程之間是非同步並發
關於主進程和子進程,你需要注意的點:
1.多個進程之間是非同步並發的程式,因為cpu的調度策略問題,不一定哪個任務先執行,哪個任務後執行.
整體而言,主進程比子進程創建的速度要快,cpu遇到阻塞會立刻切換任務,等到阻塞態的任務變成了就緒態,cpu再回來執行
2.主程式會默認等到所有的子程式執行結束之後,在統一關閉程式,釋放資源.
若不等待,有可能在後台存有多個未執行結束的子進程,會變成殭屍進程,不停的佔用cpu,記憶體
增加系統的壓力,所有方便於對進程的管理,主進程默認等待子進程.
def func(n): time.sleep(random.randrange(3)) print("數字{}<=>1.子進程id>>{},2父進程id>>{}".format(n,os.getpid(),os.getppid())) if __name__ == "__main__": for i in range(1,11): Process(target=func,args=(i,)).start() print("主進程執行結束了....") print(os.getpid())
執行結果如下圖所示
join:先子後主
1.join基本語法
def func(): print("發送第一封郵箱,要求漲工資") if __name__ == "__main__": p = Process(target=func) p.start() # 必須等待子進程全部執行結束之後,在執行主進程中的程式碼,用join來同步子父進程. p.join() # time.sleep(1) print("發送第二封郵箱,漲到一個月6萬")
執行結果如下圖所示
2.join:多個子進程
def func(i): time.sleep(1) print("發送第%s封郵箱,要求升職加薪" % (i)) if __name__ == "__main__": lst = [] for i in range(10): p = Process(target=func, args=(i,)) p.start() lst.append(p) # 把創建的十個子進程對象方放到列表中,現在他們處於就緒態 for i in lst: i.join() # 十個子進程對象同時join print("主進程發最後一封郵件:此致敬禮~")
執行結果如下圖所示
請注意!!!千萬不要寫成如下寫法:
守護進程deamon
1.守護進程的基本概念
概念:
守護進程守護的是主進程,如果主進程中的所有程式碼執行完畢了,
當前這個守護進程會被立刻殺死,立刻終止.
語法:
進程.daemon = True—->設置當前這個進程為守護進程
必須寫在start()調用進程之前進行設置
2.守護進程的基本使用方法
def func(): print("start當前子進程") time.sleep(1) print("end當前子進程") if __name__ == "__main__": p = Process(target=func) p.daemon = True p.start() print("主進程執行結束 ... ")
執行結果如下圖所示
3.守護進程:多個子進程
def func1(): count = 1 while True: print("*" * count) time.sleep(0.5) count += 1 def func2(): print("start func2 當前子進程任務") time.sleep(3) print("end func2 當前子進程任務") if __name__ == "__main__": p1 = Process(target=func1) p2 = Process(target=func2) # 設置p1這個進程對象為守護進程 p1.daemon = True p1.start() p2.start() time.sleep(1) print("主進程執行結束 ... ")
執行結果如下圖所示
4.守護進程實際用途:監控報活
# 守護進行 def alive(): while True: print("給監控的總伺服器發消息,報告自己的存活狀態, i am alive~") time.sleep(1) # 執行任務 def func(): while True: try: time.sleep(1) raise RuntimeError print("當前5號伺服器功能:對日誌進行數據分析.... ") except: break # pass if __name__ == "__main__": # 創建2個子進程 p1 = Process(target=alive) p2 = Process(target=func) # 設置p1為守護進程 p1.daemon = True p1.start() p2.start() # 必須等到p2任務執行結束之後,在向下執行. p2.join() print("當前伺服器狀態異常 ... ")
在一切都很正常的時候,它的運行結果是這樣的
當出現問題時,它的運行結果是這樣的
兩張和進程相關的圖