一 鎖(Lock)json
當多個進程使用同一份數據資源的時候,就會引起數據安全或順序混亂問題。就會用到鎖安全
例如:買火車票,我如今只有一張票,10我的來買,若是不加鎖,就會顯示10我的都買到網絡
1 from multiprocessing import Process,Lock 2 import time,json,random 3 def search():#查票 4 dic=json.load(open('db')) 5 print('\033[31m剩餘票數%s\033[0m' %dic['count']) 6 7 def get(num):#買票 8 dic=json.load(open('db')) 9 time.sleep(random.random()) #模擬讀數據的網絡延遲 10 if dic['count'] >0: 11 dic['count']-=1 12 time.sleep(random.random()) #模擬寫數據的網絡延遲 13 json.dump(dic,open('db','w')) 14 print('\033[31m用戶%s購票成功\033[0m'%num) 15 16 def task(num,lock): 17 search() 18 lock.acquire() 19 get(num) 20 lock.release() 21 22 if __name__ == '__main__': 23 lock = Lock() 24 for i in range(10): #模擬併發10個客戶端搶票 25 p=Process(target=task,args = (i,lock)) 26 p.start()
還有我開啓三個進程讓一一對應啓動和結束一樣也用到了鎖併發
1 import os 2 import time 3 import random 4 from multiprocessing import Process,Lock 5 6 def work(n,lock): 7 lock.acquire()#取的鑰匙 8 print('%s:%s is running'%(n,os.getpid())) 9 time.sleep(random.random()) 10 print('%s:%s is done' %(n,os.getpid())) 11 lock.release()#釋放 12 if __name__ == '__main__': 13 lock=Lock() 14 for i in range(3): 15 p=Process(target=work,args=(i,lock)) 16 p.start() 17 18 結果: 19 0:25068 is running 20 0:25068 is done 21 1:24296 is running 22 1:24296 is done 23 2:24092 is running 24 2:24092 is done
二 事件(Event)(用的不多)app
# 事件內部內置了一個標誌
# wait 方法 若是這個標誌是True,那麼wait == pass
# wait 方法 若是這個標誌是False,那麼wait就會陷入阻塞,一直阻塞到標誌從False變成True
# 一個事件在建立之初 內部的標誌默認是False
# Flase -> True set()
# True -> False clear()
例子:紅路燈模型
說明:
# 10個進程 模擬車 :車的行走要依靠當時的交通燈
# 交通燈是綠燈 車就走
# 交通燈是紅燈 車就停 停到燈變綠
# wait 來等燈
# set clear 來控制燈
1 from multiprocessing import Process, Event 2 import time, random 3 4 def car(e, n): 5 while True: 6 if not e.is_set(): 7 # 進程剛開啓,is_set()的值是Flase,模擬信號燈爲紅色 8 print('\033[31m紅燈亮\033[0m,car%s等着' % n) 9 e.wait() # 阻塞,等待is_set()的值變成True,模擬信號燈爲綠色 10 print('\033[32m車%s 看見綠燈亮了\033[0m' % n) 11 time.sleep(random.randint(3, 6)) 12 if not e.is_set(): #若是is_set()的值是Flase,也就是紅燈,仍然回到while語句開始 13 continue 14 print('車開遠了,car', n) 15 break 16 17 def traffic_lights(e, inverval): 18 while True: 19 time.sleep(inverval) # 先睡3秒 20 if e.is_set(): # 標誌是True 21 print('######', e.is_set()) 22 e.clear() # ---->將is_set()的值設置爲False 23 else: # 標誌是False 24 e.set() # ---->將is_set()的值設置爲True 25 print('***********',e.is_set()) 26 27 28 if __name__ == '__main__': 29 e = Event() #e就是事件 30 t = Process(target=traffic_lights, args=(e, 3)) # 建立一個進程控制紅綠燈 31 for i in range(10): 32 p=Process(target=car,args=(e,i,)) # 建立10個進程控制10輛車 33 p.start() 34 t.start() 35 36 print('============》')
三 隊列 (Queue)dom
q.get( [ block [ ,timeout ] ] )
返回q中的一個項目。若是q爲空,此方法將阻塞,直到隊列中有項目可用爲止。block用於控制阻塞行爲,默認爲True. 若是設置爲False,將引起Queue.Empty異常(定義在Queue模塊中)。timeout是可選超時時間,用在阻塞模式中。若是在制定的時間間隔內沒有項目變爲可用,將引起Queue.Empty異常。
q.get_nowait( )
同q.get(False)方法。
q.put(item [, block [,timeout ] ] )
將item放入隊列。若是隊列已滿,此方法將阻塞至有空間可用爲止。block控制阻塞行爲,默認爲True。若是設置爲False,將引起Queue.Empty異常(定義在Queue庫模塊中)。timeout指定在阻塞模式中等待可用空間的時間長短。超時後將引起Queue.Full異常。
建立共享的進程隊列,Queue是多進程安全的隊列,能夠使用Queue實現多進程之間的數據傳遞。 ui
例子:spa
1 from multiprocessing import Queue,Process 2 3 def func(q,num): 4 try: 5 t = q.get_nowait() #拿一張票 不阻塞直接報錯同q.get(False)
6 print("%s搶到票了"%num) 7 except:pass 8 9 if __name__ == '__main__': 10 q = Queue() 11 q.put(1) #往裏面放一張票 12 for i in range(10):#建立了10我的去搶一張票 13 Process(target=func,args=(q,i)).start() 14 15 16 #結果是隻有一我的買到了票
四信號量 (Semaphore)瞭解便可,不多用線程
如:code
互斥鎖同時只容許一個線程更改數據,而信號量Semaphore是同時容許必定數量的線程更改數據 。
假設商場裏有4個迷你唱吧,因此同時能夠進去4我的,若是來了第五我的就要在外面等待,等到有人出來才能再進去玩
1 from multiprocessing import Process,Semaphore 2 import time,random 3 def go_ktv(sem,user): 4 sem.acquire() 5 print('%s佔到一件ktv小屋' %user) 6 time.sleep(random.randint(3,5)) 7 sem.release() 8 print('%s走出小屋'%user) 9 if __name__ == '__main__': 10 sem=Semaphore(4) 11 p_l=[] 12 for i in range(13): 13 p=Process(target=go_ktv,args=(sem,'user%s' %i,)) 14 p.start() 15 p_l.append(p) 16 for i in p_l: 17 i.join() 18 print('##########')