進程是系統進行資源分配和調度的基本單位,進程表示程序正在執行的過程,是‘活的’,而程序就是一推躺在硬盤上的代碼,是‘死的’。
成都創新互聯主營太谷網站建設的網絡公司,主營網站建設方案,app軟件開發公司,太谷h5小程序定制開發搭建,太谷網站營銷推廣歡迎太谷等地區企業咨詢
1.先來先服務調度算法:對長作業有利,對短作業無利
2.短作業優先調度算法:對短作業有利,對長作業無利
3.時間片輪轉法+多級反饋隊列
該方法是指,將時間片切成n份,每一份表示一個時間片,這些時間片有一個優先級順序,最上面的優先執行,一個長任務第一個時間片沒有完成會被放到第二個,如果第一個時間片有來任務會優先等第一個執行完在執行第二個。
from multiprocessing import Process # 導入進程模塊
import time
# 子進程函數
def func(name):
print('支線%s'% name)
time.sleep(3)
print('over%s'% name)
# windows下創建進程,一定要在main下面創建
# 因為windows創建進程類似于模塊導入的方式,會從上往下依次執行,如果放在main外面,會一直創建進程下去
# linux系統中只是將代碼拷貝一份,因此不需要在main下面創建
# main表示當該文件是執行文件時才會被運行,該文件是導入的形式時不會被運行
if __name__ == '__main__':
# 1.創建進程對象
# 參數1:需要創建進程的目標函數;
# 參數2:需要給函數傳的參數是一個元組形式,當需要傳的參數是一個時,注意加一個,
p = Process(target=func,args=('yun',))
# 2.開啟進程,告訴操作系統創建進程,操作系統會去申請一個內存空間,把子進程丟進去執行
p.start()
# 3.下面是主進程的執行
print('主')
from multiprocessing import Process
import time
# 1.創建一個類,該類繼承Process類
class MyProcess(Process):
# 2.類中子進程的函數名必須是run
def run(self):
print('hello')
time.sleep(1)
print('gun')
if __name__ == '__main__':
# 3.產生類的對象
p = MyProcess()
# 4.開啟進程
p.start()
print('主')
總結:
1.創建進程實際上就是在內存中申請了一塊內存空間,將代碼丟進去運行
2.一個進程產生一個內存空間,多個進程產生多個內存空間
3.進程之間默認是無法進行數據交互的,如果需要交互需要借助第三方模塊,在子進程修改全局變量,全局變量不會改變
join方法是用來讓主進程代碼等待調用join的子進程代碼運行結束之后,在運行主進程!
p1.join()
p2.join()
p3.join()
print('主')
如果p2和p3不調用join方法,主進程就不會等待其運行結束后再運行!!!
一臺計算機上面運行著很多進程,那么計算機是如何區分并管理著這些進程,計算機會給這些進程各自分配一個pid
在windows終端,可以通過tasklist命令查看所有的進程pid
tasklist |findstr PID 查看具體進程的命令
在mac電腦,可以通過ps aux查看
ps aux|grep PID 查看具有進程的命令
進程的其他方法:
from multiprocessing import Process,current_process
import time
import os
def func():
# current_process().pid 獲取當前進程的進程id
print('%s 正在運行'% current_process().pid)
time.sleep(2)
if __name__ == '__main__':
p = Process(target=func)
p.start()
# os.getpid()也是獲取當前進程id的方法
p.terminate() # 殺死當前進程,系統幫您殺死該進程,需要一定的時間,所有下面的is_alive可能為true
print(p.is_alive()) # 判斷當前進程是否存活
print('主',os.getpid())
# os.getppid()是獲取當前父id的方法
print('主主',os.getppid())
僵尸進程:
當子進程死了,子進程并不會立即占用的進程id號,因為需要讓父進程查看到子進程的id、運行時間等信息,所有進程會步入僵尸進程
回收子進程的id號:1,負進程調用join()方法 2.父進程等待子進程運行完畢
孤兒進程:
子進程存活,父進程意外死亡。
操作系統會幫你自動回收子進程的資源
"你死我也不獨活" p.daemon = True 方法設置守護進程
from multiprocessing import Process,current_process
import time
def func():
print('奴隸活著')
time.sleep(2)
print('奴隸死去')
if __name__ == '__main__':
p = Process(target=func)
p.daemon = True # 將p這個子進程設置成守護進程,這一句話一定要放在start前面,否則保錯
p.start()
print('主人死了')
多個進程操作同一個數據的時候,很可能會出現數據錯亂的問題
針對上述問題,解決方案就是加鎖處理:將并發變成串行,犧牲效率保證數據的安全準確
# 1.導入鎖模塊
from multiprocessing import Process LOCK
# 2.在主進程中生成一把鎖,讓所有子進程去搶這把鎖,mutex 需要傳入對應函數的參數里面
mutex = LOCK()
# 3.在需要加鎖的功能上面
mutex.acquire()
# 4.在功能執行完的下面,解鎖
mutex.release()
總結:
1.鎖不要輕易使用,容易造成鎖死的現象
2.鎖只在需要爭搶數據的時候使用,保證數據的安全
進程之間是無法相互通信的,因此需要采用第三方模塊隊列queue。
注意:隊列中的數據是先進先出的。
# 導入隊列模塊
import queue
# 也可以用下面這種方式之間導入到隊列類
from multiprocessing import Queue
# 1.生成一個隊列對象
q = queue.Queue(3) # 括號內可以傳數字,表示隊列可以最大存放的數據量,不傳有一個很大的默認值
# 2.給隊列存數據
q.put(111)
print(q.full()) # 判斷當前隊列是否存滿
q.put(222)
print(q.empty()) # 判斷當前隊列是否為空
q.put(333)
print(q.full())
# q.put(444) # 當給隊列存的數據個數超過隊列的最大存放數,隊列會進入阻塞狀態等待位置
# 3.從隊列中取值
v1 = q.get()
v2 = q.get()
v3 = q.get()
# v4 = q.get() 當隊列中沒有數據的時候,在次取值會使得隊列進入阻塞
v5 = q.get_nowait() # 當隊列中沒有數據可取的時候,就報錯
v6 = q.get(timeout=3) # 沒有數據原地等待3秒,然后報錯
print(v1,v2,v3)
# 總結:
'''
q.full()
q.empty()
q.get_nowait()
這三個方法在多進程下是不精確的
'''
IPC機制:
1.子進程和主進程之間的通信
2.子進程和子進程之間的通信
from multiprocessing import Queue,Process
def cosumer1(q):
# 在子進程中存數據
q.put('我是隊列存的信息')
print('子進程1')
def cosumer2(q):
# 在子進程中取數據
print(q.get())
if __name__ == '__main__':
q = Queue()
p = Process(target=cosumer1,args=(q,))
p1 = Process(target=cosumer2,args=(q,))
p.start()
p1.start()
# 在主進程取出數據
# print(q.get())
補充:后進先出q、優先級q
import queue
q = queue.LifoQueue(3)
q.put(11)
q.put(22)
print(q.get()) # 后進先出,后放入的數據先取出來
q = queue.PriorityQueue(3)
q.put((1,'444')) # put方法里面放的是一個元組,元組第一個元素表示優先級,第二個是需要放的數據
q.put(((-3,)))
q.put((10,'434'))
print(q.get()) # 優先級數字越小的級別越高,優先取出
from multiprocessing import Queue,Process,JoinableQueue
import time
import random
# 生產者子進程
def producer(name,food,q):
for i in range(5):
print('%s生產了%s%s'%(name,food,i))
time.sleep(random.randint(1,3))
q.put(food)
def consumer(name,q):
# 消費者一直在吃,進入循環
while True:
food = q.get() # 當隊列中沒有東西的時候,該子進程會被卡住,進入阻塞狀態
print('%s吃了%s'%(name,food))
q.task_done() # 該方法屬于JoinableQueue,作用是告訴隊列你已經從隊列中取出一個數據并且處理完畢了
if __name__ == '__main__':
# 將q = Queue()改成下面的方法創建隊列
q = JoinableQueue()
# 兩個生產者,分別生產的東西放進隊列中
p1 = Process(target=producer,args=('zhang','包子',q))
p2 = Process(target=producer, args=('yang', '粥', q))
# 消費者從隊列中取出東西吃掉
c1 = Process(target=consumer,args=('www',q))
p1.daemon = True # 守護主進程,主進程結束殺死子進程
p2.daemon = True
c1.daemon = True
p1.start()
p2.start()
c1.start()
p1.join()
p2.join() # 等待生產者生產完畢在執行下面的代碼
q.join() # 等待隊列中所有的數據被取完之后再執行下述代碼
# JoinableQueue類
"""
該類是在queue類上的基礎上添加了一個計數器,每當往隊列中存放一個數據時,計數器會加1;
當你調用task_done時,計數器減1
q.join() 等待計數器為0的時候在執行該方法下面的代碼
"""
文章名稱:進程
地址分享:http://www.hntjjpw.com/article6/dsogiog.html
成都網站建設公司_創新互聯,為您提供定制網站、定制開發、外貿網站建設、手機網站建設、微信小程序、響應式網站
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯