2018.11.08python學習第三十六天
阿新 • • 發佈:2018-11-08
一:守護程序
# 守護程序:顧名思義,就是一個程序守護著另一個程序,指的是兩個程序之間的關係。
# 特點:就是守護程序在被守護程序死亡時,也會跟著被守護程序的死亡而死亡。
使用方法:
from multiprocessing import Process import time def task(): print('hello') time.sleep(3) print('see u') if __name__ == '__main__': p = Process(target = task) p.daemon = True p.start() time.sleep(3) # print('process is running') # 1.daemon必須在start之前寫 # 2.當主程序死亡時,守護程序也會死亡,如果註釋掉time.sleep(3),守護程序還沒來得及執 行就死亡。
二:互斥鎖
#當多個程序對統一資源進行讀寫時,這些程序會對這個資源產生競爭,從而導致資料錯亂,解決方法就是將這些程序變成序列。那麼我們可以用下面的辦法來解決:
1.join #把整個程序變成序列,並且順序是固定的。
# 雖然join可以將程序變成序列,但是序列是順序是我們人為固定的,對於這些競爭的程序來說不公# 平,而且,當我們需要部分序列的時候,整個時候join顯然不是很適用
# 那麼由此產生了另一種辦法
2.互斥鎖 # 可以實現並程中的部分序列,
使用方法
from multiprocessing import Process,Lock def task1(lock): lock.acquire() for i in range(10000): print('===') def task2(lock): lock.acquire() for i in range(10000): print("===============") lock.release() def task3(lock): lock.acquire() for i in range(10000): print("======================================") lock.release() if __name__ == '__main__': mutex = lock() p1 = Process(target=task1,args=(mutex,)) p2 = Process(target=task2,args=(mutex,)) p3 = Process(target=task3,args=(mutex,)) p1.start() p2.start() p3.start() print('over') # 1.先匯入模組Lock # 2.建立一個鎖物件 mutex = Lock() # 3.將程序競爭的資源上鎖
注意:所有的程序上鎖的話必須使用同一把鎖
三:互斥鎖應用
搶票程式
from multiprocessing import Process,Lock import json,time,random # file = {"count":1} # json 格式 def show_ticket(name): # 模擬網路延遲 time.sleep(random.randint(1,5)) with open ('filename','rt',encoding = 'utf-8') as f: data = json.load(f) print('%s查看了車票剩餘:%s' %(name,data['count'])) def buy_ticket(name): with open ('filename','rt',encoding = 'utf-8') as f: data = json.load(f) if data['count'] > 0: data['count'] -=1 time.sleep(random.randint(1,3)) time.sleep(random.randint(1,3)) with open('filename','wt',encoding = 'utf-8') as f1: json.dump(data,f1) print('%s購票成功' %name) def task(lock,name): show_ticket(name) lock.acquire() buy_ticket(name) lock.release() if __name__ == '__main__': lock = Lock() for i in range(1,11): p = Process(target = task,args = (lock,'客戶%s' %i)) p.start()
四:ipc
# 程序彼此之間互相隔離,要實現程序間通訊(ipc/inter process commucation),
# multiprocessing模組支援兩種形式:佇列和管道,這兩種方式都是使用訊息傳遞的
建立佇列的類(底層就是以管道和鎖定的方式實現的):
# Queue([maxsize]):建立共享程序佇列,Queue是多程序安全的佇列,可以使用Queue實現多進# 程之間的資料傳遞
引數介紹
1.maxsize #是佇列中允許最大項數,省略則需大小限制
方法一介紹
q = Queue()
1.q.put #方法用以插入資料到佇列中,put方法還有兩個引數可以選擇:blocked和timeout。 # 如果block為True(預設),並且timeout為正值,該方法會阻塞timeout指定的時間,直到 # 該佇列有剩餘的空間。如果超時,會丟擲Queue.Full異常。
# 如果block為False,但是Queue已經滿了,會立即丟擲Queue.Full異常。
2.q.get #方法可以從佇列取走一個元素(注意是取走)。同樣有兩個方法引數可以選擇:block和# timeout.
# 如果blocked為True(預設值),並且timeout為正值,那麼在等待時間內沒有取到任何元素,# 會丟擲Queue.Empty異常。
# 如果blocked為False,有兩種情況存在,如果Queue有一個值可用,則立即返回該值,否則,如# 果佇列為空,則立即丟擲Queue.Empty異常.
3.q.get_nowwait() # 同q.get(False)
4.q.put_nowwait() # 同q.put(False)
5.q.empty() # 呼叫此方法時q為空則返回True,該結果不可靠,如在返回True的過程中又 添加了專案。
6.q.full() # 呼叫此方法時q已滿則返回True,該結果不可靠,如在返回True的過程中隊 列中的專案又被取走了。
7.q.qsize() # 返回佇列中目前專案正確數量,結果也不可靠,和上述一致。
舉例
from multiprocessing import Queue
# 建立一個佇列
q = Queue()
# 存入資料
q.put('hello) # 存入str
q.put(['1','2','3']) # 存入list
q.put(1) # 存入int
# 讀出資料
print(q.get())
print(q.get())
print(q.get())
# 阻塞操作
q = Queue(3) # 限制存放資料的個數
# 存入資料
q.put('hello',block = False) # 不阻塞
q.put(['1','2','3'],block = False) # 不阻塞
q.put(1,block =False) # 不阻塞
# 此時再存入一個數據q.put('word',block = False) 則會丟擲Queue.Full異常
# 如果是q.put('word',block = True)則不會丟擲異常,會等到Queue有位置後再存入
# 取出資料
print(q.get(block=False))
print(q.get(block=False))
print(q.get(block=False))
# 此時再取出一個數據print(q.get(block = False)) 則會丟擲Queue.Empty異常
# 如果是print(q.gte(block = True)則不會丟擲異常,會等到Queue有資料後再取走
方法二:
# 匯入Manager模組
from multiprocessing import Process,Manager
import time
def task(dic):
print('subprocess is running')
li[0] = 1
print(li)
if __name__ == "__main__":
m = Manager()
# 建立一個公共區域
li = m.list([100])
p = Process(target = task,args = (li,))
p.start()
time.sleep(3)
print(li)
# m = Manager()只能建立list和dict,其他型別則共享不了