Python全棧之進程和守護進程
1. 理解進程
進程的概念:(process)
進程就是正在運行的程序,它是操作系統(tǒng)中,資源分配的最小單位. 資源分配:分配的是cpu和內(nèi)存等物理資源 進程號是進程的唯一標識 同一個程序執(zhí)行兩次之后是兩個進程 進程和進程之間的關(guān)系: 數(shù)據(jù)彼此隔離,通過socket通信
并行和并發(fā):
并發(fā):一個cpu同一時間不停執(zhí)行多個程序 并行:多個cpu同一時間不停執(zhí)行多個程序

cpu的進程調(diào)度的方法:
# 先來先服務(wù)fcfs(first come first server):先來的先執(zhí)行 # 短作業(yè)優(yōu)先算法:分配的cpu多,先把短的算完 # 時間片輪轉(zhuǎn)算法:每一個任務(wù)就執(zhí)行一個時間片的時間.然后就執(zhí)行其他的. # 多級反饋隊列算法 越是時間長的,cpu分配的資源越少,優(yōu)先級靠后 越是時間短的,cpu分配的資源越多

1、2、3、4作業(yè)分別給0.4秒,1作業(yè)完成,2、3、4作業(yè)沒有完成,會放到二級隊列中,把后續(xù)短的作業(yè)放到一級隊列。二級隊列中的作業(yè)分別給0.3秒,2號作業(yè)完成,3、4號作業(yè)放到三級隊列,分別給0.2秒,3作業(yè)完成,4號沒有完成,放到四號隊列,給0.1秒進行處理,1號作業(yè)有可能是下載作業(yè)。
進程三狀態(tài)圖:

(1)就緒(Ready)狀態(tài) 只剩下CPU需要執(zhí)行外,其他所有資源都已分配完畢 稱為就緒狀態(tài)。 (2)執(zhí)行(Running)狀態(tài) cpu開始執(zhí)行該進程時稱為執(zhí)行狀態(tài)。 (3)阻塞(Blocked)狀態(tài) 由于等待某個事件發(fā)生而無法執(zhí)行時,便是阻塞狀態(tài),cpu執(zhí)行其他進程.例如,等待I/O完成input、申請緩沖區(qū)不能滿足等等。

同步 異步 / 阻塞 非阻塞:
場景在多任務(wù)當中 同步:必須等我這件事干完了,你在干,只有一條主線,就是同步 異步:沒等我這件事情干完,你就在干了,有兩條主線,就是異步 阻塞:比如代碼有了input,就是阻塞,必須要輸入一個字符串,否則代碼不往下執(zhí)行 非阻塞:沒有任何等待,正常代碼往下執(zhí)行. # 同步阻塞 :效率低,cpu利用不充分 # 異步阻塞 :比如socketserver,可以同時連接多個,但是彼此都有recv # 同步非阻塞:沒有類似input的代碼,從上到下執(zhí)行.默認的正常情況代碼 # 異步非阻塞:效率是最高的,cpu過度充分,過度發(fā)熱 液冷
守護進程:
#可以給子進程貼上守護進程的名字,該進程會隨著主進程代碼執(zhí)行完畢而結(jié)束(為主進程守護) (1)守護進程會在主進程代碼執(zhí)行結(jié)束后就終止 (2)守護進程內(nèi)無法再開啟子進程,否則拋出異常(了解)
鎖(Lock):
lock.acquire()# 上鎖 lock.release()# 解鎖 #同一時間允許一個進程上一把鎖 就是Lock 加鎖可以保證多個進程修改同一塊數(shù)據(jù)時,同一時間只能有一個任務(wù)可以進行修改,即串行的修改,沒錯,速度是慢了,但犧牲速度卻保證了數(shù)據(jù)安全。 #同一時間允許多個進程上多把鎖 就是[信號量Semaphore] 信號量是鎖的變形: 實際實現(xiàn)是 計數(shù)器 + 鎖,同時允許多個進程上鎖 # 互斥鎖Lock : 互斥鎖就是進程的互相排斥,誰先搶到資源,誰就上鎖改資源內(nèi)容,為了保證數(shù)據(jù)的同步性 # 注意:多個鎖一起上,不開鎖,會造成死鎖.上鎖和解鎖是一對.
2. 進程的語法
# ### 進程 process
import os,time
"""
# ps -aux 查看進程號
# ps -aux | grep 2784 過濾查找2784這個進程
# 強制殺死進程
kill -9 進程號
# 獲取當前進程號
res = os.getpid()
print(res)
# 獲取當前進程的父進程
res = os.getppid()
print(res)
"""
from multiprocessing import Process
# (1) 進程的使用
"""
def func():
# 1.子進程id:3561,2.父進程id:3560
print("1.子進程id:{},2.父進程id:{}".format(os.getpid(),os.getppid()))
if __name__ == "__main__":
# 創(chuàng)建子進程 ,返回進程對象
p = Process(target=func)
# 調(diào)用子進程
p.start()
# 3.主進程id:3560,4.父進程id:3327
print("3.主進程id:{},4.父進程id:{}".format(os.getpid(),os.getppid()))
"""
# (2) 創(chuàng)建帶有參數(shù)的進程
"""
def func(n):
time.sleep(1)
for i in range(1,n+1): # 0 ~ n-1
print(i)
print("1.子進程id:{},2.父進程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) 進程之間的數(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) 進程之間的異步性
"""
1.多個進程之間是異步的并發(fā)程序,因為cpu調(diào)度策略問題,不一定先執(zhí)行哪一個任務(wù)
默認來看,主進程執(zhí)行速度稍快于子進程,因為子進程創(chuàng)建時,要分配空間資源可能會阻塞
阻塞態(tài),cpu會立刻切換任務(wù),以讓程序整體的速度效率最大化
2.默認主進程要等待所有的子進程執(zhí)行結(jié)束之后,在統(tǒng)一關(guān)閉程序,釋放資源
若不等待,子進程可能不停的在系統(tǒng)的后臺占用cpu和內(nèi)存資源形成僵尸進程.
為了方便進程的管理,主進程默認等待子進程.在統(tǒng)一關(guān)閉程序;
"""
def func(n):
print("1.子進程id:{},2.父進程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("主進程執(zhí)行結(jié)束了 ... " , os.getpid() )
3. join自定義進程類
子進程全部執(zhí)行完,在執(zhí)行主進程
# ### 1.同步主進程和子進程 : join
"""必須等待當前的這個子進程執(zhí)行結(jié)束之后,再去執(zhí)行下面的代碼;,用來同步子父進程;"""
from multiprocessing import Process
import time
# (1) join 的基本使用
"""
def func():
print("發(fā)送第一封郵件 : 我的親親領(lǐng)導,你在么?")
if __name__ == "__main__":
p = Process(target=func)
p.start()
# time.sleep(0.1)
p.join()
print("發(fā)送第二封郵件 : 我想說,工資一個月給我漲到6萬")
"""
# (2) 多進程場景中的join
"""
def func(i):
time.sleep(1)
print("發(fā)送第一封郵件{} : 我的親親領(lǐng)導,你在么?".format(i))
if __name__ == "__main__":
lst = []
for i in range(1,11):
p = Process(target=func,args=(i,))
p.start()
# join 寫在里面會導致程序變成同步
lst.append(p)
# 把所有的進程對象都放在列表中,統(tǒng)一使用.join進行管理;
for i in lst:
i.join()
print("發(fā)送第二封郵件 : 我想說,工資一個月給我漲到6萬")
"""
# ### 2使用自定義進程類,創(chuàng)建進程
# (1) 基本語法
import os
class MyProcess(Process):
def run(self):
print("1.子進程id:{},2.父進程id:{}".format(os.getpid(),os.getppid()))
if __name__ == "__main__":
p = MyProcess()
p.start()
# (2) 帶有參數(shù)的自定義進程類
class MyProcess(Process):
def __init__(self,name):
# 手動調(diào)用一下父類的構(gòu)造方法,完成系統(tǒng)成員的初始化;
super().__init__()
self.name = name
def run(self):
print("1.子進程id:{},2.父進程id:{}".format(os.getpid(),os.getppid()))
print(self.name)
if __name__ == "__main__":
p = MyProcess("我是參數(shù)")
p.start()
4. 守護進程
# ### 守護進程
"""
守護進程守護的是主進程,當主進程所有代碼執(zhí)行完畢之后,立刻強制殺死守護進程;
"""
from multiprocessing import Process
import time
# (1) 基本語法
"""
def func():
# time.sleep(1)
print("start... 當前的子進程")
print("end ... 當前的子進程")
if __name__ == "__main__":
p = Process(target=func)
# 在進程啟動之前,設(shè)置守護進程
p.daemon = True
p.start()
print("主進程執(zhí)行結(jié)束 ... ")
"""
# (2) 多個子進程的守護場景;
"""默認主進程等待所有非守護進程,也就是子進程執(zhí)行結(jié)束之后,在關(guān)閉程序,釋放資源
守護進程只要在主進程代碼執(zhí)行結(jié)束時,就會自動關(guān)閉;
"""
"""
def func1():
print("start ... func1 執(zhí)行當前子進程 ... ")
print("end ... func1 結(jié)束當前子進程 ... ")
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這個進程變成守護進程;
p2.daemon = True
p1.start()
p2.start()
print("主進程執(zhí)行結(jié)束 ... ")
"""
# (3) 守護進程用途: 監(jiān)控報活
def alive():
while True:
print("3號服務(wù)器向總監(jiān)控服務(wù)器發(fā)送報活信息: i am ok~")
time.sleep(1)
def func():
while True:
try:
print("3號服務(wù)器負責抗住3萬用戶量的并發(fā)訪問...")
time.sleep(3)
# 主動拋出執(zhí)行錯誤的異常,觸發(fā)except分支
raise RuntimeError
except:
print("3號服務(wù)器扛不住了.. 快來修理我..")
break
if __name__ == "__main__":
p1 = Process(target=alive)
p2 = Process(target=func)
p1.daemon = True
p1.start()
p2.start()
# 必須等待p2這個子進程執(zhí)行完畢之后,再放行主進程下面的代碼
# 下面主進程代碼執(zhí)行結(jié)束,立刻殺死守護進程,失去了報活功能;
p2.join()
print("主進程執(zhí)行結(jié)束 .... ")
#作業(yè):
""" 使用多進程的方式 完成tcp服務(wù)端的并發(fā) """
小提示:
在調(diào)用的時候觸發(fā)裝飾器 連續(xù)發(fā)包的時候才會粘包 容器不能轉(zhuǎn)化成字節(jié)流,機器交互用json 文件對象是迭代器,迭代器返回的數(shù)據(jù)是一行行返回的 創(chuàng)建子進程的時候,要為其分配資源,處于堵塞狀態(tài), 會去執(zhí)行下面的程序,這就是異步執(zhí)行,兩條主線 不刷新頁面就能發(fā)文數(shù)據(jù)的技術(shù)叫ajax,是一種異步程序 進程是典型的異步程序 看一下super()這個函數(shù) 默認主進程走完了守護進程會立即被殺死,但是會等待子進程運行完畢
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Python 開發(fā)工具PyCharm安裝教程圖文詳解(新手必看)
PyCharm是一種Python IDE,帶有一整套可以幫助用戶在使用Python語言開發(fā)時提高其效率的工具,比如調(diào)試、語法高亮、Project管理、代碼跳轉(zhuǎn)、智能提示、自動完成、單元測試、版本控制。今天通過本文給大家分享PyCharm安裝教程,一起看看吧2020-02-02
python中str內(nèi)置函數(shù)用法總結(jié)
在本篇文章里小編給大家整理了一篇關(guān)于python中str內(nèi)置函數(shù)用法總結(jié)內(nèi)容,有需要的朋友們可以學習下。2020-12-12

