Python全棧之進(jìn)程和守護(hù)進(jìn)程
1. 理解進(jìn)程
進(jìn)程的概念:(process
)
進(jìn)程就是正在運(yùn)行的程序,它是操作系統(tǒng)中,資源分配的最小單位. 資源分配:分配的是cpu和內(nèi)存等物理資源 進(jìn)程號(hào)是進(jìn)程的唯一標(biāo)識(shí) 同一個(gè)程序執(zhí)行兩次之后是兩個(gè)進(jìn)程 進(jìn)程和進(jìn)程之間的關(guān)系: 數(shù)據(jù)彼此隔離,通過socket通信
并行和并發(fā):
并發(fā):一個(gè)cpu同一時(shí)間不停執(zhí)行多個(gè)程序 并行:多個(gè)cpu同一時(shí)間不停執(zhí)行多個(gè)程序
cpu的進(jìn)程調(diào)度的方法:
# 先來先服務(wù)fcfs(first come first server):先來的先執(zhí)行 # 短作業(yè)優(yōu)先算法:分配的cpu多,先把短的算完 # 時(shí)間片輪轉(zhuǎn)算法:每一個(gè)任務(wù)就執(zhí)行一個(gè)時(shí)間片的時(shí)間.然后就執(zhí)行其他的. # 多級(jí)反饋隊(duì)列算法 越是時(shí)間長的,cpu分配的資源越少,優(yōu)先級(jí)靠后 越是時(shí)間短的,cpu分配的資源越多
1、2、3、4作業(yè)分別給0.4秒,1作業(yè)完成,2、3、4作業(yè)沒有完成,會(huì)放到二級(jí)隊(duì)列中,把后續(xù)短的作業(yè)放到一級(jí)隊(duì)列。二級(jí)隊(duì)列中的作業(yè)分別給0.3秒,2號(hào)作業(yè)完成,3、4號(hào)作業(yè)放到三級(jí)隊(duì)列,分別給0.2秒,3作業(yè)完成,4號(hào)沒有完成,放到四號(hào)隊(duì)列,給0.1秒進(jìn)行處理,1號(hào)作業(yè)有可能是下載作業(yè)。
進(jìn)程三狀態(tài)圖:
(1)就緒(Ready)狀態(tài) 只剩下CPU需要執(zhí)行外,其他所有資源都已分配完畢 稱為就緒狀態(tài)。 (2)執(zhí)行(Running)狀態(tài) cpu開始執(zhí)行該進(jìn)程時(shí)稱為執(zhí)行狀態(tài)。 (3)阻塞(Blocked)狀態(tài) 由于等待某個(gè)事件發(fā)生而無法執(zhí)行時(shí),便是阻塞狀態(tài),cpu執(zhí)行其他進(jìn)程.例如,等待I/O完成input、申請(qǐng)緩沖區(qū)不能滿足等等。
同步 異步 / 阻塞 非阻塞:
場(chǎng)景在多任務(wù)當(dāng)中 同步:必須等我這件事干完了,你在干,只有一條主線,就是同步 異步:沒等我這件事情干完,你就在干了,有兩條主線,就是異步 阻塞:比如代碼有了input,就是阻塞,必須要輸入一個(gè)字符串,否則代碼不往下執(zhí)行 非阻塞:沒有任何等待,正常代碼往下執(zhí)行. # 同步阻塞 :效率低,cpu利用不充分 # 異步阻塞 :比如socketserver,可以同時(shí)連接多個(gè),但是彼此都有recv # 同步非阻塞:沒有類似input的代碼,從上到下執(zhí)行.默認(rèn)的正常情況代碼 # 異步非阻塞:效率是最高的,cpu過度充分,過度發(fā)熱 液冷
守護(hù)進(jìn)程:
#可以給子進(jìn)程貼上守護(hù)進(jìn)程的名字,該進(jìn)程會(huì)隨著主進(jìn)程代碼執(zhí)行完畢而結(jié)束(為主進(jìn)程守護(hù)) (1)守護(hù)進(jìn)程會(huì)在主進(jìn)程代碼執(zhí)行結(jié)束后就終止 (2)守護(hù)進(jìn)程內(nèi)無法再開啟子進(jìn)程,否則拋出異常(了解)
鎖(Lock):
lock.acquire()# 上鎖 lock.release()# 解鎖 #同一時(shí)間允許一個(gè)進(jìn)程上一把鎖 就是Lock 加鎖可以保證多個(gè)進(jìn)程修改同一塊數(shù)據(jù)時(shí),同一時(shí)間只能有一個(gè)任務(wù)可以進(jìn)行修改,即串行的修改,沒錯(cuò),速度是慢了,但犧牲速度卻保證了數(shù)據(jù)安全。 #同一時(shí)間允許多個(gè)進(jìn)程上多把鎖 就是[信號(hào)量Semaphore] 信號(hào)量是鎖的變形: 實(shí)際實(shí)現(xiàn)是 計(jì)數(shù)器 + 鎖,同時(shí)允許多個(gè)進(jìn)程上鎖 # 互斥鎖Lock : 互斥鎖就是進(jìn)程的互相排斥,誰先搶到資源,誰就上鎖改資源內(nèi)容,為了保證數(shù)據(jù)的同步性 # 注意:多個(gè)鎖一起上,不開鎖,會(huì)造成死鎖.上鎖和解鎖是一對(duì).
2. 進(jìn)程的語法
# ### 進(jìn)程 process import os,time """ # ps -aux 查看進(jìn)程號(hào) # ps -aux | grep 2784 過濾查找2784這個(gè)進(jìn)程 # 強(qiáng)制殺死進(jìn)程 kill -9 進(jìn)程號(hào) # 獲取當(dāng)前進(jìn)程號(hào) res = os.getpid() print(res) # 獲取當(dāng)前進(jìn)程的父進(jìn)程 res = os.getppid() print(res) """ from multiprocessing import Process # (1) 進(jìn)程的使用 """ def func(): # 1.子進(jìn)程id:3561,2.父進(jìn)程id:3560 print("1.子進(jìn)程id:{},2.父進(jìn)程id:{}".format(os.getpid(),os.getppid())) if __name__ == "__main__": # 創(chuàng)建子進(jìn)程 ,返回進(jìn)程對(duì)象 p = Process(target=func) # 調(diào)用子進(jìn)程 p.start() # 3.主進(jìn)程id:3560,4.父進(jìn)程id:3327 print("3.主進(jìn)程id:{},4.父進(jìn)程id:{}".format(os.getpid(),os.getppid())) """ # (2) 創(chuàng)建帶有參數(shù)的進(jìn)程 """ def func(n): time.sleep(1) for i in range(1,n+1): # 0 ~ n-1 print(i) print("1.子進(jìn)程id:{},2.父進(jìn)程id:{}".format(os.getpid(),os.getppid())) if __name__ == "__main__": n = 6 # target=指定任務(wù) args = 參數(shù)元組 p = Process(target=func , args=(n,)) p.start() for i in range(1,n+1): print("*" * i) """ # (3) 進(jìn)程之間的數(shù)據(jù)彼此隔離 """ total = 100 def func(): global total total +=1 print(total) if __name__ == "__main__": p = Process(target=func) p.start() time.sleep(1) print(total) """ # (4) 進(jìn)程之間的異步性 """ 1.多個(gè)進(jìn)程之間是異步的并發(fā)程序,因?yàn)閏pu調(diào)度策略問題,不一定先執(zhí)行哪一個(gè)任務(wù) 默認(rèn)來看,主進(jìn)程執(zhí)行速度稍快于子進(jìn)程,因?yàn)樽舆M(jìn)程創(chuàng)建時(shí),要分配空間資源可能會(huì)阻塞 阻塞態(tài),cpu會(huì)立刻切換任務(wù),以讓程序整體的速度效率最大化 2.默認(rèn)主進(jìn)程要等待所有的子進(jìn)程執(zhí)行結(jié)束之后,在統(tǒng)一關(guān)閉程序,釋放資源 若不等待,子進(jìn)程可能不停的在系統(tǒng)的后臺(tái)占用cpu和內(nèi)存資源形成僵尸進(jìn)程. 為了方便進(jìn)程的管理,主進(jìn)程默認(rèn)等待子進(jìn)程.在統(tǒng)一關(guān)閉程序; """ def func(n): print("1.子進(jìn)程id:{},2.父進(jìn)程id:{}".format(os.getpid(),os.getppid()) , n ) if __name__ == "__main__": for i in range(1,11): p = Process(target=func,args=(i,)) p.start() print("主進(jìn)程執(zhí)行結(jié)束了 ... " , os.getpid() )
3. join自定義進(jìn)程類
子進(jìn)程全部執(zhí)行完,在執(zhí)行主進(jìn)程
# ### 1.同步主進(jìn)程和子進(jìn)程 : join """必須等待當(dāng)前的這個(gè)子進(jìn)程執(zhí)行結(jié)束之后,再去執(zhí)行下面的代碼;,用來同步子父進(jìn)程;""" from multiprocessing import Process import time # (1) join 的基本使用 """ def func(): print("發(fā)送第一封郵件 : 我的親親領(lǐng)導(dǎo),你在么?") if __name__ == "__main__": p = Process(target=func) p.start() # time.sleep(0.1) p.join() print("發(fā)送第二封郵件 : 我想說,工資一個(gè)月給我漲到6萬") """ # (2) 多進(jìn)程場(chǎng)景中的join """ def func(i): time.sleep(1) print("發(fā)送第一封郵件{} : 我的親親領(lǐng)導(dǎo),你在么?".format(i)) if __name__ == "__main__": lst = [] for i in range(1,11): p = Process(target=func,args=(i,)) p.start() # join 寫在里面會(huì)導(dǎo)致程序變成同步 lst.append(p) # 把所有的進(jìn)程對(duì)象都放在列表中,統(tǒng)一使用.join進(jìn)行管理; for i in lst: i.join() print("發(fā)送第二封郵件 : 我想說,工資一個(gè)月給我漲到6萬") """ # ### 2使用自定義進(jìn)程類,創(chuàng)建進(jìn)程 # (1) 基本語法 import os class MyProcess(Process): def run(self): print("1.子進(jìn)程id:{},2.父進(jìn)程id:{}".format(os.getpid(),os.getppid())) if __name__ == "__main__": p = MyProcess() p.start() # (2) 帶有參數(shù)的自定義進(jìn)程類 class MyProcess(Process): def __init__(self,name): # 手動(dòng)調(diào)用一下父類的構(gòu)造方法,完成系統(tǒng)成員的初始化; super().__init__() self.name = name def run(self): print("1.子進(jìn)程id:{},2.父進(jìn)程id:{}".format(os.getpid(),os.getppid())) print(self.name) if __name__ == "__main__": p = MyProcess("我是參數(shù)") p.start()
4. 守護(hù)進(jìn)程
# ### 守護(hù)進(jìn)程 """ 守護(hù)進(jìn)程守護(hù)的是主進(jìn)程,當(dāng)主進(jìn)程所有代碼執(zhí)行完畢之后,立刻強(qiáng)制殺死守護(hù)進(jìn)程; """ from multiprocessing import Process import time # (1) 基本語法 """ def func(): # time.sleep(1) print("start... 當(dāng)前的子進(jìn)程") print("end ... 當(dāng)前的子進(jìn)程") if __name__ == "__main__": p = Process(target=func) # 在進(jìn)程啟動(dòng)之前,設(shè)置守護(hù)進(jìn)程 p.daemon = True p.start() print("主進(jìn)程執(zhí)行結(jié)束 ... ") """ # (2) 多個(gè)子進(jìn)程的守護(hù)場(chǎng)景; """默認(rèn)主進(jìn)程等待所有非守護(hù)進(jìn)程,也就是子進(jìn)程執(zhí)行結(jié)束之后,在關(guān)閉程序,釋放資源 守護(hù)進(jìn)程只要在主進(jìn)程代碼執(zhí)行結(jié)束時(shí),就會(huì)自動(dòng)關(guān)閉; """ """ def func1(): print("start ... func1 執(zhí)行當(dāng)前子進(jìn)程 ... ") print("end ... func1 結(jié)束當(dāng)前子進(jìn)程 ... ") def func2(): count = 1 while True: print("*" * count) time.sleep(1) count += 1 if __name__ == "__main__": p1 = Process(target=func1) p2 = Process(target=func2) # 把p2這個(gè)進(jìn)程變成守護(hù)進(jìn)程; p2.daemon = True p1.start() p2.start() print("主進(jìn)程執(zhí)行結(jié)束 ... ") """ # (3) 守護(hù)進(jìn)程用途: 監(jiān)控報(bào)活 def alive(): while True: print("3號(hào)服務(wù)器向總監(jiān)控服務(wù)器發(fā)送報(bào)活信息: i am ok~") time.sleep(1) def func(): while True: try: print("3號(hào)服務(wù)器負(fù)責(zé)抗住3萬用戶量的并發(fā)訪問...") time.sleep(3) # 主動(dòng)拋出執(zhí)行錯(cuò)誤的異常,觸發(fā)except分支 raise RuntimeError except: print("3號(hào)服務(wù)器扛不住了.. 快來修理我..") break if __name__ == "__main__": p1 = Process(target=alive) p2 = Process(target=func) p1.daemon = True p1.start() p2.start() # 必須等待p2這個(gè)子進(jìn)程執(zhí)行完畢之后,再放行主進(jìn)程下面的代碼 # 下面主進(jìn)程代碼執(zhí)行結(jié)束,立刻殺死守護(hù)進(jìn)程,失去了報(bào)活功能; p2.join() print("主進(jìn)程執(zhí)行結(jié)束 .... ") #作業(yè): """ 使用多進(jìn)程的方式 完成tcp服務(wù)端的并發(fā) """
小提示:
在調(diào)用的時(shí)候觸發(fā)裝飾器 連續(xù)發(fā)包的時(shí)候才會(huì)粘包 容器不能轉(zhuǎn)化成字節(jié)流,機(jī)器交互用json 文件對(duì)象是迭代器,迭代器返回的數(shù)據(jù)是一行行返回的 創(chuàng)建子進(jìn)程的時(shí)候,要為其分配資源,處于堵塞狀態(tài), 會(huì)去執(zhí)行下面的程序,這就是異步執(zhí)行,兩條主線 不刷新頁面就能發(fā)文數(shù)據(jù)的技術(shù)叫ajax,是一種異步程序 進(jìn)程是典型的異步程序 看一下super()這個(gè)函數(shù) 默認(rèn)主進(jìn)程走完了守護(hù)進(jìn)程會(huì)立即被殺死,但是會(huì)等待子進(jìn)程運(yùn)行完畢
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
- python 如何設(shè)置守護(hù)進(jìn)程
- Python 創(chuàng)建守護(hù)進(jìn)程的示例
- Python守護(hù)進(jìn)程實(shí)現(xiàn)過程詳解
- python實(shí)現(xiàn)守護(hù)進(jìn)程、守護(hù)線程、守護(hù)非守護(hù)并行
- python使用fork實(shí)現(xiàn)守護(hù)進(jìn)程的方法
- Python如何實(shí)現(xiàn)守護(hù)進(jìn)程的方法示例
- python daemon守護(hù)進(jìn)程實(shí)現(xiàn)
- Python守護(hù)進(jìn)程用法實(shí)例分析
- Python實(shí)現(xiàn)日志備份守護(hù)進(jìn)程的示例
相關(guān)文章
python實(shí)現(xiàn)socket簡單通信的示例代碼
這篇文章主要介紹了python實(shí)現(xiàn)socket簡單通信的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04python全棧要學(xué)什么 python全棧學(xué)習(xí)路線
在本文中小編給大家整理了關(guān)于python全棧要學(xué)什么以及python全棧學(xué)習(xí)路線的知識(shí)點(diǎn)內(nèi)容,需要的朋友們參考下。2019-06-06Python 開發(fā)工具PyCharm安裝教程圖文詳解(新手必看)
PyCharm是一種Python IDE,帶有一整套可以幫助用戶在使用Python語言開發(fā)時(shí)提高其效率的工具,比如調(diào)試、語法高亮、Project管理、代碼跳轉(zhuǎn)、智能提示、自動(dòng)完成、單元測(cè)試、版本控制。今天通過本文給大家分享PyCharm安裝教程,一起看看吧2020-02-02Python字符串常用方法以及其應(yīng)用場(chǎng)景詳解
本人學(xué)習(xí)python時(shí)的總結(jié),并不需要記住,知道有這個(gè)方法,拿起來用就行,下面這篇文章主要給大家介紹了關(guān)于Python字符串常用方法以及其應(yīng)用場(chǎng)景的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08python中str內(nèi)置函數(shù)用法總結(jié)
在本篇文章里小編給大家整理了一篇關(guān)于python中str內(nèi)置函數(shù)用法總結(jié)內(nèi)容,有需要的朋友們可以學(xué)習(xí)下。2020-12-12