進(jìn)程調(diào)度
1、先來先服務(wù)
2不瓶、短作業(yè)優(yōu)先
3禾嫉、時(shí)間片輪轉(zhuǎn)
4、多級(jí)反饋隊(duì)列
僵尸進(jìn)程與孤兒進(jìn)程
1蚊丐、僵尸進(jìn)程:進(jìn)程結(jié)束了熙参,資源還沒來得及回收
2、孤兒進(jìn)程:主進(jìn)程掛了麦备,子進(jìn)程還沒結(jié)束孽椰,它就會(huì)被專門的進(jìn)程接管
進(jìn)程間數(shù)據(jù)隔離
進(jìn)程間的數(shù)據(jù)是獨(dú)有的昭娩,不同進(jìn)程間不能相互使用
進(jìn)程對(duì)象及其他方法
1、windows:tasklist | findstr 進(jìn)程id號(hào)
2黍匾、mac,linux:ps aux | grep 進(jìn)程id號(hào)
3栏渺、進(jìn)程對(duì)象:t = Process(target = task, )或者是在進(jìn)程內(nèi)部:current_process()
4、t.pid或者current_process().pid 獲得進(jìn)程id號(hào)
5膀捷、os.getpid() 同上迈嘹,獲取進(jìn)程id號(hào)
6、os.getppid() 獲取父進(jìn)程id號(hào)全庸,子進(jìn)程中獲取父進(jìn)程id秀仲,等于父進(jìn)程的id號(hào)
7、t.is_alive()或者current_process().is_alive() 查看進(jìn)程是否存活
8壶笼、t.terminate() 關(guān)閉進(jìn)程神僵,在主進(jìn)程關(guān)閉
pid、ppid的用法
from multiprocessing import Process,current_process
import os,time
def task():
print('子進(jìn)程開始')
print('在子進(jìn)程中查看自己的id:%s'%current_process().pid)
print('在子進(jìn)程中查看自己的id:%s'%os.getpid())
print('在子進(jìn)程中查看父進(jìn)程的id:%s'%os.getppid())
time.sleep(1)
print('子進(jìn)程結(jié)束')
if __name__ == '__main__':
t = Process(target=task)
t.start()
print('在主進(jìn)程中查看子進(jìn)程的id:%s'%t.pid)
print('在主進(jìn)程中查看自己的id:%s'%os.getpid())
print('在主進(jìn)程中查看父進(jìn)程的id:%s'%os.getppid())
# time.sleep(1)
print('主進(jìn)程結(jié)束')
#在主進(jìn)程中查看子進(jìn)程的id:8652
#在主進(jìn)程中查看自己的id:14888
#在主進(jìn)程中查看父進(jìn)程的id:4564
#主進(jìn)程結(jié)束
#子進(jìn)程開始
#在子進(jìn)程中查看自己的id:8652
#在子進(jìn)程中查看自己的id:8652
#在子進(jìn)程中查看父進(jìn)程的id:14888
#子進(jìn)程結(jié)束
name覆劈、is_alive保礼、terminate用法
from multiprocessing import Process,current_process
import os,time
def foo(n,tag):
print(f'子進(jìn)程{tag} 開啟')
print('當(dāng)前進(jìn)程的名字:%s'%current_process().name)
time.sleep(n)
print(f'子進(jìn)程{tag} 關(guān)閉')
if __name__ == '__main__':
t1 = Process(target=foo,args=(3,1))
t2 = Process(target=foo,args=(2,2))
t1.start()
t2.start()
t1.terminate() # 給操作系統(tǒng)發(fā)了一個(gè)終止進(jìn)程的請(qǐng)求
time.sleep(0.0000069)
print(t1.is_alive()) # 判斷進(jìn)程是否活著
t2.join()
print(t1.is_alive())
print('子進(jìn)程的名字:%s'%t1.name)
print('子進(jìn)程的名字:%s' %t2.name)
#False
#子進(jìn)程2 開啟
#當(dāng)前進(jìn)程的名字:Process-2
#子進(jìn)程2 關(guān)閉
#False
#子進(jìn)程的名字:Process-1
#子進(jìn)程的名字:Process-2
守護(hù)進(jìn)程
from multiprocessing import Process
import time,os
def task(n,tag):
print('%s is running'%tag)
time.sleep(n)
print('%s is done'%tag)
if __name__ == '__main__':
t = Process(target=task,args=(5,'子進(jìn)程'))
t.daemon = True #守護(hù)進(jìn)程:主進(jìn)程一旦結(jié)束,子進(jìn)程也結(jié)束责语,一定要加在啟動(dòng)之前
t.start()
time.sleep(2)
print('主進(jìn)程結(jié)束')
互斥鎖
作用:---為了防止多進(jìn)程操作同一個(gè)數(shù)據(jù)(文件)炮障,數(shù)據(jù)寫亂了的問題。
---要在進(jìn)程寫數(shù)據(jù)的時(shí)候加鎖坤候,并行變成串行胁赢,犧牲了效率,保證了安全白筹。
from multiprocessing import Process, Lock
import json,time
def search():
with open('ticket.json','r',encoding='utf-8') as f:
dic = json.load(f)
print(f'余票還有{dic.get("count")}')
return dic
def buy():
dic = search()
time.sleep(1) # 模擬網(wǎng)絡(luò)IO
if dic.get('count') > 0:
dic['count'] -= 1
with open('ticket.json','w',encoding='utf-8') as f:
json.dump(dic,f)
time.sleep(1.5) #模擬網(wǎng)絡(luò)IO
print('購票成功')
else:
print('購票失敗')
def task(mutex):
search() #查看過程不加鎖智末,每個(gè)人都能查看
# mutex.acquire() # 買票過程要加鎖,買前加鎖
# buy() # 10個(gè)進(jìn)程不能并發(fā)了徒河,只能串行執(zhí)行
# mutex.release() # 買后釋放鎖
with mutex:
buy() # 這兩步相當(dāng)于上面的三步
if __name__ == '__main__':
mutex = Lock() # 在主進(jìn)程中創(chuàng)建鎖
for i in range(10): # 模擬十人買票(開10個(gè)進(jìn)程)
t = Process(target=task,args=(mutex,))
t.start()
隊(duì)列介紹
q = Queue(隊(duì)列大小)
q.put() 放值
q.put_nowait() 隊(duì)列滿了系馆,放不進(jìn)去就不放了,報(bào)錯(cuò)
q.get() 從隊(duì)列頭部取出一個(gè)值
q.get_nowait() 從隊(duì)列頭部取值顽照,沒有就報(bào)錯(cuò)
print(q.empty()) 查看隊(duì)列是不是空的
print(q.full()) 查看隊(duì)列是不是滿的
from multiprocessing import Queue
q = Queue(5)
q.put(1)
q.put(2)
q.put(3)
q.put('qe')
q.put_nowait(100)
print(q.get())
print(q.get())
print(q.get(timeout=100))
print(q.get_nowait())
print(q.empty())
print(q.full())
IPC機(jī)制(進(jìn)程間通信)
from multiprocessing import Process,Queue
import os,time
def task1(q):
print('我是進(jìn)程1由蘑,id是%s'%os.getpid())
q.put('nihao')
q.put('111')
q.put('222')
def task2(q):
res = q.get()
q.get()
print(q.empty()) # 查看隊(duì)列是否為空
print('我是進(jìn)程2,id是%s'%os.getpid(),res)
if __name__ == '__main__':
q = Queue(5)
t1 = Process(target=task1,args=(q,))
t1.start()
t2 = Process(target=task2,args=(q,))
t2.start()
print(q.get())
上下文管理器的使用
魔法方法:在進(jìn)行特定的操作時(shí)會(huì)自動(dòng)被調(diào)用(如:enter代兵、exit纵穿、init等)
用魔法方法實(shí)現(xiàn)上下文管理器讀模式
class MyClass():
def __init__(self,file_name,mode,encoding):
self.file_name = file_name
self.mode = mode
self.encoding = encoding
def __enter__(self):
#只要有with就會(huì)執(zhí)行
self.file = open(self.file_name,self.mode,encoding=self.encoding)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
#只要頂格寫代碼就會(huì)執(zhí)行
self.file.close()
with MyClass('ticket.json','r',encoding='utf-8') as f:
print(f.read())