進(jìn)程是系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位,進(jìn)程表示程序正在執(zhí)行的過程,是‘活的’,而程序就是一推躺在硬盤上的代碼,是‘死的’。

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