day31 程序和其他方法,鎖,佇列
阿新 • • 發佈:2019-01-14
1.程序的其他方法:
首先引入模組:
import os
from multiprocessing import Process
p = Process(target=f,)
程序的id: p.pid 或者os.getpid 或者os.getppid
程序的名字: p.name
檢視程序是否活著: p.is_alive #返回一個ture或者false
p.terminate 給作業系統傳送一個結束程序的訊號
import time
import os
from multiprocessing import Process
# def f1():
# print('子程序的pid',os.getpid())
# print('子程序的父程序的pid',os.getppid())
# print('aaa')
#
# def f2():
# print('bbb')
#
#
# if __name__ == '__main__':
#
# p1 = Process(target=f1,name='寶寶1')
# p2 = Process(target=f2,)
# p1.start()
# p2.start()
# print(p1.name )
# print('子程序的pid',p1.pid)
# print('父程序的id',os.getpid())
#程序的其他方法
def f1():
time.sleep(5)
print('子程序1號')
if __name__ == '__main__':
p = Process(target=f1,)
p.start()
print(p.is_alive()) #判斷子程序是否還活著,是否還在執行
p.terminate() #給作業系統傳送一個結束程序的訊號
time.sleep(0.5)
print(p.is_alive())
2.驗證程序之間是空間隔離的
: 區域性引入全域性變數,在區域性進行變數的重新賦值,檢視全域性變數是否被更改,如果沒有更改,證明程序之間是空間隔離的,否則程序不是空間隔離的.
from multiprocessing import Process
num = 100
def f1():
global num
num= 3
print('子程序中的num',num)
print(">>>>>>>",num)
if __name__ == '__main__':
p=Process(target=f1,)
p.start()
p.join() ##等到子程序結束之後,主程序才能關閉
print('主程序中的num',num)
# >>>>>>> 100
# >>>>>>> 100
# 子程序中的num 3
# 主程序中的num 100
3.守護程序
p.deamon = True 守護程序,必須寫在start之前,主程序的程式碼執行完成,設定為守護程序的子程序會隨之結束
import time
from multiprocessing import Process
def f1():
time.sleep(3)
print('xxx')
def f2():
time.sleep(5)
print('普通子程序的程式碼')
if __name__ == '__main__':
p = Process(target=f1,)
p.daemon =True #將該程序設定為守護程序,必須寫在start之前,意思是如果我的主程序程式碼執行結束了,你這子程序不管執行到什麼地方,都直接結束
p.start()
#開啟一個不同的子程序來驗證一下守護程序的結束只和主程序的程式碼執行結束有關係,而整個程式的結束需要主程序的子程序的程式碼都執行結束才結束
p2 = Process(target=f2,)
p2.start()
#等待2號普通程序的結束,才繼續執行寫面主程序中的程式碼
# p2.join()
#守護程序會跟隨父程序的程式碼結束,就結束
print('主程序結束')
4.程序鎖(同步鎖/互斥鎖)
鎖:保證資料的安全,但是犧牲了效率,枷鎖的這段程式碼變成了(同步)序列執行的狀態,又叫同步鎖/互斥鎖(重點)
a.第一種寫法
loc =Lock()
loc.acquire()
需要鎖的程式碼
loc.release()
b.第二種寫法
with loc:
需要鎖的程式碼
# 互斥鎖/程序鎖/同步鎖
# import json
import time
from multiprocessing import Process,Lock
def show_t(i):
with open('ticket','r',encoding='utf-8') as f:
ticket_data = f.read()
# print(ticket_data)
t_data = eval(ticket_data)
# print(t_data,type(t_data))
print('%s查詢剩餘票數為%s'%(i,t_data['count']))
def get_t(i,l1):
l1.acquire()
with open('ticket', 'r', encoding='utf-8') as f:
ticket_data = f.read()
# print(ticket_data)
t_data = eval(ticket_data)
# print(t_data,type(t_data))
# print('%s查詢剩餘票數為%s' % (i, t_data['count']))
if t_data['count'] > 0:
t_data['count'] -= 1
print('%s搶票成功'%i)
time.sleep(0.2)
with open('ticket', 'w') as f:
f.write(str(t_data))
else:
print('沒票了!!!')
l1.release()
if __name__ == '__main__':
l1 = Lock()
for i in range(10):
p1 = Process(target=show_t,args=(i,))
p1.start()
for i in range(10):
p2 = Process(target=get_t,args=(i,l1) )
p2.start()
5.資料的共享
Manager() 資料共享,也需要在匯入程序模組使用
import time
from multiprocessing import Process,Manager,Lock
def f1(m_d,l2):
# m_d['num'] -= 1 #
with l2:
# l2.acquire()
tmp = m_d['num']
tmp -= 1
time.sleep(0.1)
m_d['num'] = tmp
# l2.release()
if __name__ == '__main__':
m = Manager()
l2 = Lock()
m_d = m.dict({'num':100})
p_list = []
for i in range(10):
p = Process(target=f1,args=(m_d,l2))
p.start()
p_list.append(p)
[pp.join() for pp in p_list]
print(m_d['num'])
6佇列(重點) Queue()
q = Queue(10)
q.put() 放資料
q.get() 取資料
q.qsize() 返回的是當前佇列中內容的長度
q.put_nowait() 不等待,但是報錯
q.get_nowait() 不等待,但是報錯
q.full() 因為這個東西不可靠,滿了返回一個True,不滿返回一個False
q.empty() 因為這個東西不可靠,空了返回一個True,不空返
from multiprocessing import Process,Queue
q = Queue(3) #建立一個佇列物件,佇列長度為3,先進先出
q.put(1)
# print('>>>>>',q.qsize()) #返回當前佇列的內容長度
print(q.full())
q.put(2)
# print('>>>>>',q.qsize())
q.put(3)
print(q.full()) #q.full()瞭解,因為這個東西不可靠,滿了返回一個True,不滿返回一個False
# print('sss')
# q.put(4) #放入資料的時候,如果佇列滿了了,程式會在你put操作的地方阻塞
# try:
# q.put_nowait(4) #不阻塞程式,但是會報錯queue.Full,可以通過捕獲異常來進行其他的操作
# except:
# print('佇列滿了,玩別的去吧')
# print('xxx')
print(q.get())
print(q.get())
print(q.get())
print('是不是空了呀:',q.empty()) #q.empty()瞭解,因為這個東西不可靠,空了返回一個True,不空返
# q.put(4)
# print('是不是空了呀:',q.empty()) #True或者False,因為q在put資料的時候,有一個細微的延遲
# 回一個False
# print(q.get()) #如果佇列空了,程式會在這個地方卡主,也就是阻塞程式
try:
q.get_nowait() #queue.Empty
except:
print('佇列空了,搞得別的事情')
print('拿多啦')
7.JoinableQueue
task_done() 給佇列返回一個任務處理完畢的訊號
join() 等待放入佇列的人物全部執行完畢,也就是等待
task_done()
的訊號數量等於放入佇列中的所有任務的數量,不然會阻塞
import time
from multiprocessing import Process,Queue,JoinableQueue
#生產者
def producer(q):
for i in range(10):
time.sleep(0.2)
s = '大包子%s號'%i
print(s+'新鮮出爐,拿去用')
q.put(s)
q.join() #就等著task_done()訊號的數量,和我put進去的數量相同時,才繼續執行
print('所有的任務都被處理了,繼續潛行吧騷年們')
def consumer(q):
while 1:
time.sleep(0.5)
baozi = q.get()
print(baozi+'被吃了')
q.task_done() #給佇列傳送一個取出的這個任務已經處理完畢的訊號
if __name__ == '__main__':
# q = Queue(30)
q = JoinableQueue(30) #同樣是一個長度為30的佇列
pro_p = Process(target=producer,args=(q,))
con_p = Process(target=consumer,args=(q,))
pro_p.start()
con_p.daemon = True
con_p.start()
pro_p.join()
print('主程序結束')
1.程序的其他方法: 首先引入模組: import os from multiprocessing import Process p = Process(target=f,) 程序的id: p.pid 或者os.getpid 或者os.getppid 程序的名字: p.name 檢視程序是否活著: p.is_alive #返回一個ture或者false p.terminate 給作業系統傳送一個結束程序的訊號 import time import os from multiprocessing import Process # def f1(): # print('子程序的pid',os.getpid()) # print('子程序的父程序的pid',os.getppid()) # print('aaa') # # def f2(): # print('bbb') # # # if __name__ == '__main__': # # p1 = Process(target=f1,name='寶寶1') # p2 = Process(target=f2,) # p1.start() # p2.start() # print(p1.name) # print('子程序的pid',p1.pid) # print('父程序的id',os.getpid()) #程序的其他方法 def f1(): time.sleep(5) print('子程序1號') if __name__ == '__main__': p = Process(target=f1,) p.start() print(p.is_alive()) #判斷子程序是否還活著,是否還在執行 p.terminate() #給作業系統傳送一個結束程序的訊號 time.sleep(0.5) print(p.is_alive()) 2.驗證程序之間是空間隔離的 : 區域性引入全域性變數,在區域性進行變數的重新賦值,檢視全域性變數是否被更改,如果沒有更改,證明程序之間是空間隔離的,否則程序不是空間隔離的. from multiprocessing import Process num = 100 def f1(): global num num= 3 print('子程序中的num',num) print(">>>>>>>",num) if __name__ == '__main__': p=Process(target=f1,) p.start() p.join() ##等到子程序結束之後,主程序才能關閉 print('主程序中的num',num) # >>>>>>> 100 # >>>>>>> 100 # 子程序中的num 3 # 主程序中的num 100 3.守護程序 p.deamon = True 守護程序,必須寫在start之前,主程序的程式碼執行完成,設定為守護程序的子程序會隨之結束 import time from multiprocessing import Process def f1(): time.sleep(3) print('xxx') def f2(): time.sleep(5) print('普通子程序的程式碼') if __name__ == '__main__': p = Process(target=f1,) p.daemon =True #將該程序設定為守護程序,必須寫在start之前,意思是如果我的主程序程式碼執行結束了,你這子程序不管執行到什麼地方,都直接結束 p.start() #開啟一個不同的子程序來驗證一下守護程序的結束只和主程序的程式碼執行結束有關係,而整個程式的結束需要主程序的子程序的程式碼都執行結束才結束 p2 = Process(target=f2,) p2.start() #等待2號普通程序的結束,才繼續執行寫面主程序中的程式碼 # p2.join() #守護程序會跟隨父程序的程式碼結束,就結束 print('主程序結束') 4.程序鎖(同步鎖/互斥鎖) 鎖:保證資料的安全,但是犧牲了效率,枷鎖的這段程式碼變成了(同步)序列執行的狀態,又叫同步鎖/互斥鎖(重點) a.第一種寫法 loc =Lock() loc.acquire() 需要鎖的程式碼 loc.release() b.第二種寫法 with loc: 需要鎖的程式碼 # 互斥鎖/程序鎖/同步鎖 # import json import time from multiprocessing import Process,Lock def show_t(i): with open('ticket','r',encoding='utf-8') as f: ticket_data = f.read() # print(ticket_data) t_data = eval(ticket_data) # print(t_data,type(t_data)) print('%s查詢剩餘票數為%s'%(i,t_data['count'])) def get_t(i,l1): l1.acquire() with open('ticket', 'r', encoding='utf-8') as f: ticket_data = f.read() # print(ticket_data) t_data = eval(ticket_data) # print(t_data,type(t_data)) # print('%s查詢剩餘票數為%s' % (i, t_data['count'])) if t_data['count'] > 0: t_data['count'] -= 1 print('%s搶票成功'%i) time.sleep(0.2) with open('ticket', 'w') as f: f.write(str(t_data)) else: print('沒票了!!!') l1.release() if __name__ == '__main__': l1 = Lock() for i in range(10): p1 = Process(target=show_t,args=(i,)) p1.start() for i in range(10): p2 = Process(target=get_t,args=(i,l1) ) p2.start() 5.資料的共享 Manager() 資料共享,也需要在匯入程序模組使用 import time from multiprocessing import Process,Manager,Lock def f1(m_d,l2): # m_d['num'] -= 1 # with l2: # l2.acquire() tmp = m_d['num'] tmp -= 1 time.sleep(0.1) m_d['num'] = tmp # l2.release() if __name__ == '__main__': m = Manager() l2 = Lock() m_d = m.dict({'num':100}) p_list = [] for i in range(10): p = Process(target=f1,args=(m_d,l2)) p.start() p_list.append(p) [pp.join() for pp in p_list] print(m_d['num']) 6佇列(重點) Queue() q = Queue(10) q.put() 放資料 q.get() 取資料 q.qsize() 返回的是當前佇列中內容的長度 q.put_nowait() 不等待,但是報錯 q.get_nowait() 不等待,但是報錯 q.full() 因為這個東西不可靠,滿了返回一個True,不滿返回一個False q.empty() 因為這個東西不可靠,空了返回一個True,不空返 from multiprocessing import Process,Queue q = Queue(3) #建立一個佇列物件,佇列長度為3,先進先出 q.put(1) # print('>>>>>',q.qsize()) #返回當前佇列的內容長度 print(q.full()) q.put(2) # print('>>>>>',q.qsize()) q.put(3) print(q.full()) #q.full()瞭解,因為這個東西不可靠,滿了返回一個True,不滿返回一個False # print('sss') # q.put(4) #放入資料的時候,如果佇列滿了了,程式會在你put操作的地方阻塞 # try: # q.put_nowait(4) #不阻塞程式,但是會報錯queue.Full,可以通過捕獲異常來進行其他的操作 # except: # print('佇列滿了,玩別的去吧') # print('xxx') print(q.get()) print(q.get()) print(q.get()) print('是不是空了呀:',q.empty()) #q.empty()瞭解,因為這個東西不可靠,空了返回一個True,不空返 # q.put(4) # print('是不是空了呀:',q.empty()) #True或者False,因為q在put資料的時候,有一個細微的延遲 # 回一個False # print(q.get()) #如果佇列空了,程式會在這個地方卡主,也就是阻塞程式 try: q.get_nowait() #queue.Empty except: print('佇列空了,搞得別的事情') print('拿多啦') 7.JoinableQueue task_done() 給佇列返回一個任務處理完畢的訊號 join() 等待放入佇列的人物全部執行完畢,也就是等待 task_done() 的訊號數量等於放入佇列中的所有任務的數量,不然會阻塞 import time from multiprocessing import Process,Queue,JoinableQueue #生產者 def producer(q): for i in range(10): time.sleep(0.2) s = '大包子%s號'%i print(s+'新鮮出爐,拿去用') q.put(s) q.join() #就等著task_done()訊號的數量,和我put進去的數量相同時,才繼續執行 print('所有的任務都被處理了,繼續潛行吧騷年們') def consumer(q): while 1: time.sleep(0.5) baozi = q.get() print(baozi+'被吃了') q.task_done() #給佇列傳送一個取出的這個任務已經處理完畢的訊號 if __name__ == '__main__': # q = Queue(30) q = JoinableQueue(30) #同樣是一個長度為30的佇列 pro_p = Process(target=producer,args=(q,)) con_p = Process(target=consumer,args=(q,)) pro_p.start() con_p.daemon = True con_p.start() pro_p.join() print('主程序結束')