-互斥鎖
對於模擬多人查票搶票
票數放在檔案中db.txt
程式
from multiprocessing import process
import json
import time
import random
import os
def search():
time.sleep(random.randint(1,3))
dic=json.load(open(r'c:\users\clt\anaconda3\lettycode\db.txt','r',encoding='utf-8'))
print('%s 檢視剩餘票數 %s' %(os.getpid(),dic['count']))
def get():
dic=json.load(open(r'c:\users\clt\anaconda3\lettycode\db.txt','r',encoding='utf-8'))
if dic['count']>0:
dic['count']-=1
time.sleep(random.randint(1,3))
json.dump(dic,open(r'c:\users\clt\anaconda3\lettycode\db.txt','w',encoding='utf-8')) #將買完票寫回
print('%s 購票成功' %os.getpid() )
def task():
search()
get()
if __name__=='__main__':
for i in range(10):
p=process(target=task)
p.start()
執行結果:錯誤
8640 檢視剩餘票數 1
14440 檢視剩餘票數 1
15580 檢視剩餘票數 1
568 檢視剩餘票數 1
18940 檢視剩餘票數 1
12868 檢視剩餘票數 1
5940 檢視剩餘票數 1
15580 購票成功
9128 檢視剩餘票數 0
16812 檢視剩餘票數 0
568 購票成功
19328 檢視剩餘票數 0
12868 購票成功
14440 購票成功
8640 購票成功
5940 購票成功
18940 購票成功
以上效率高,但是安全性低
使用整體序列,p.join()方法,效率過低
採取折中的方法,不是整體序列,只把修改資料的部分變成序列
使用互斥鎖:
#模擬多人查票、搶票
from multiprocessing import process,lock
import json
import time
import random
import os
def search():
time.sleep(random.randint(1,3))
dic=json.load(open(r'c:\users\clt\anaconda3\lettycode\db.txt','r',encoding='utf-8'))
print('%s 檢視剩餘票數 %s' %(os.getpid(),dic['count']))
def get():
dic=json.load(open(r'c:\users\clt\anaconda3\lettycode\db.txt','r',encoding='utf-8'))
if dic['count']>0:
dic['count']-=1
time.sleep(random.randint(1,3))
json.dump(dic,open(r'c:\users\clt\anaconda3\lettycode\db.txt','w',encoding='utf-8')) #將買完票寫回
print('%s 購票成功' %os.getpid() )
def task(mutex): #互斥鎖僅使得修改資料的地方序列,其他地方都是正常
mutex.acquire() #加鎖
search()
get()
mutex.release() #解鎖
if __name__=='__main__':
mutex=lock()
for i in range(10):
p=process(target=task,args=(mutex,)) #為了讓10個程序同用一把鎖,將該鎖當做引數傳過去
p.start()
結果:8160 檢視剩餘票數 1
8160 購票成功
12112 檢視剩餘票數 0
14820 檢視剩餘票數 0
2948 檢視剩餘票數 0
18004 檢視剩餘票數 0
8988 檢視剩餘票數 0
10348 檢視剩餘票數 0
1340 檢視剩餘票數 0
15012 檢視剩餘票數 0
16124 檢視剩餘票數 0
涉及到共享問題,就涉及到競爭,就得使用互斥鎖,多出地方有互斥現象就多出設鎖,不能共用一把鎖,使用互斥鎖犧牲了效率,保證了安全性
# -*- coding: utf-8 -*-
"""created on sun dec 15 09:33:05 2019
@author: clt
"""from multiprocessing import queue
q=queue(3) #佇列用來放訊息,不應該放大資料
q.put('first') #放訊息,put其實可以放任何型別的資料
q.put(2)
q.put()
print(q.get())
print(q.get())
print(q.get())
#有三個值,如果取四個就阻塞。有三個空,如果放四個沒有取也會阻塞
結果:first
2
擴充套件1,滿了不讓其阻塞,會拋異常
from multiprocessing import queue
q=queue(3) #佇列用來放訊息,不應該放大資料
q.put('first') #放訊息,put其實可以放任何型別的資料
q.put(2)
q.put()
q.put('fourth',block=false)
結果: raise full
queue.full
block=false 不讓其阻塞就拋異常
q.put_nowait() 不讓其阻塞就拋異常
q.put( ,block=true,timeout=3) 阻3秒,還不取,就拋異常
from multiprocessing import queue
q=queue(3) #佇列用來放訊息,不應該放大資料
q.put('first') #放訊息,put其實可以放任何型別的資料
q.put(2)
q.put()
#q.put('fourth',block=false)
q.put_nowait('fourth')
結果: raise full
queue.full
from multiprocessing import queue
q=queue(3) #佇列用來放訊息,不應該放大資料
q.put('first') #放訊息,put其實可以放任何型別的資料
q.put(2)
q.put()
#q.put('fourth',block=false)
#q.put_nowait('fourth')
q.put('forth',block=true,timeout=3)
結果:raise full
queue.full
#引起異常的時間慢
擴充套件2
取的時候,為空還取,並不讓其阻塞,拋異常
from multiprocessing import queue
q=queue(3) #佇列用來放訊息,不應該放大資料
q.put('first') #放訊息,put其實可以放任何型別的資料
q.put(2)
q.put()
#q.put('fourth',block=false)
#q.put_nowait('fourth')
#q.put('forth',block=true,timeout=3)
print(q.get())
print(q.get())
print(q.get())
print(q.get(block=false))
結果:first
2traceback (most recent call last):
file "c:/users/clt/anaconda3/lettycode/queue.py", line 21, in print(q.get(block=false))
file "c:\users\clt\anaconda3\lib\multiprocessing\queues.py", line 107, in get
raise empty
queue.empty
同上
q.get_nowait()
q.get(block=true,timeout=3)
程序鎖(互斥鎖)(Python)
3 搶票示例 import json import time from multiprocessing import process,lock defsearch i with open ticket encoding utf 8 as f ticket json.load f print s 當前...
互斥鎖 程序池
互斥鎖 當多個執行緒幾乎同時修改某乙個共享的資料時,需要進行同步操作,引入互斥鎖 當乙個執行緒更改資料的時候,先將它鎖定,其他執行緒不能修改,直到執行緒操作全部完成,此時會釋放資源 互斥鎖保證了同一時刻,只有乙個執行緒能對資源進行操作,保證資料的正確性 from threading import t...
thread相關 互斥鎖
互斥鎖,是一種訊號量,常用來防止兩個程序或執行緒在同一時刻訪問相同的共享資源。可以保證以下三點 原子性 把乙個互斥量鎖定為乙個原子操作,這意味著作業系統 或pthread函式庫 保證了如果乙個執行緒 鎖定了乙個互斥量,沒有其他執行緒在同一時間可以成功鎖定這個互斥量。唯一性 如果乙個執行緒鎖定了乙個互...