本文講python中的四種鎖
lock互斥鎖
使用前num = 0
def a():
global num
for _ in range(10000000):
num += 1
def b():
global num
for _ in range(10000000):
num += 1
if __name__ == '__main__':
t1=thread(target=a)
t1.start()
t2=thread(target=b)
t2.start()
t1.join()
t2.join()
print(num) #基本永遠會小於20000000
使用後num = 0
def a(lock):
global num
for _ in range(1000000):
with lock:
num += 1
def b(lock):
global num
for _ in range(1000000):
with lock:
num += 1
if __name__ == '__main__':
lock = threading.lock()
t1=thread(target=a, args=(lock,))
t1.start()
t2=thread(target=b, args=(lock,))
t2.start()
t1.join()
t2.join()
print(num) #永遠會輸出20000000
rlock重用鎖
#在之前的**中永遠不可能出現鎖在沒釋放之前重新獲得鎖,但rlock可以做到,但只能發生在乙個執行緒中,如:
num = 0
def a(lock):
with lock:
print("我是a")
b(lock)
def b(lock):
with lock:
print("我是b")
if __name__ == '__main__':
lock = threading.lock()
t1 = thread(target=a, args=(lock,))
t1.start() #會發生死鎖,因為在第一次還沒釋放鎖後,b就準備上鎖,並阻止a釋放鎖
使用後if __name__ == '__main__':
lock = threading.rlock() #只需要改變鎖為rlock程式馬上恢復
t1 = thread(target=a, args=(lock,))
t1.start()
condition同步鎖
#這個程式我們模擬甲乙對話
jlist = ["在嗎", "幹啥呢", "去玩兒不", "好吧"]
ylist = ["在呀", "玩兒手機", "不去"]
def j(list):
for i in list:
print(i)
time.sleep(0.1)
def y(list):
for i in list:
print(i)
time.sleep(0.1)
if __name__ == '__main__':
t1 = thread(target=j, args=(jlist,))
t1.start()
t1.join()
t2 = thread(target=y, args=(ylist,))
t2.start()
t2.join() #上面的程式輸出後發現效果就是咱們想要的,但是我們每次輸出後都要等待0.1秒,也無法正好確定可以拿到時間片的最短時間值,並且不能保證每次正好都是另乙個執行緒執行。因此,我們用以下方式,完美解決這些問題。
使用後jlist = ["在嗎", "幹啥呢", "去玩兒不", "好吧"]
ylist = ["在呀", "玩兒手機", "不去","哦"]
def j(cond, list):
for i in list:
with cond:
print(i)
cond.notify()
cond.wait()
def y(cond, list):
for i in list:
with cond:
cond.wait()
print(i)
cond.notify()
if __name__ == '__main__':
cond = threading.condition()
t1 = thread(target=j, args=(cond, jlist))
t2 = thread(target=y, args=(cond, ylist))
t2.start()
t1.start() #一定保證t1啟動在t2之後,因為notify傳送的訊號要被t2接受到,如果t1先啟動,會發生阻塞。
seamplore訊號量
使用前class b(threading.thread):
def __init__(self, name):
super().__init__()
self.name = name
def run(self):
time.sleep(1)
print(self.name)
class a(threading.thread):
def __init__(self):
super().__init__()
def run(self):
for i in range(100):
b = b(i)
b.start()
if __name__ == '__main__':
a = a()
a.start() #執行後發現不斷在輸出
使用後class b(threading.thread):
def __init__(self, name, sem):
super().__init__()
self.name = name
self.sem = sem
def run(self):
time.sleep(1)
print(self.name)
sem.release()
class a(threading.thread):
def __init__(self, sem):
super().__init__()
self.sem = sem
def run(self):
for i in range(100):
self.sem.acquire()
b = b(i, self.sem)
b.start()
if __name__ == '__main__':
sem = threading.semaphore(value=3)
a = a(sem)
a.start() #通過執行上面的**,我們發現一次只能輸出三個數字,sem控制訪問併發量
event事件
import time
import threading
class mythread(threading.thread):
def __init__(self, name, event):
super().__init__()
self.name = name
self.event = event
def run(self):
print('thread: {} start at {}'.format(self.name, time.ctime(time.time())))
# 等待event.set()後,才能往下執行
self.event.wait()
print('thread: {} finish at {}'.format(self.name, time.ctime(time.time())))
event = threading.event()
# 定義五個執行緒
threads = [mythread(str(i), event) for i in range(1,5)]
# 重置event,使得event.wait()起到阻塞作用
event.clear()
# 啟動所有執行緒
[t.start() for t in threads]
print('等待5s...')
time.sleep(5)
print('喚醒所有執行緒...')
event.set()
# output:
thread: 1 start at sun may 13 20:38:08 2018
thread: 2 start at sun may 13 20:38:08 2018
thread: 3 start at sun may 13 20:38:08 2018
thread: 4 start at sun may 13 20:38:08 2018
等待5s...
喚醒所有執行緒...
thread: 1 finish at sun may 13 20:38:13 2018
thread: 4 finish at sun may 13 20:38:13 2018
thread: 2 finish at sun may 13 20:38:13 2018
thread: 3 finish at sun may 13 20:38:13 2018
python 執行緒鎖
由於執行緒之間隨機排程 某執行緒可能在執行n條後,cpu接著執行其他執行緒。為了多個執行緒同時操作乙個記憶體中的資源時不產生混亂,我們使用鎖。lock 指令鎖 是可用的最低階的同步指令。lock處於鎖定狀態時,不被特定的執行緒擁有。lock包含兩種狀態 鎖定和非鎖定,以及兩個基本的方法。可以認為lo...
Python(執行緒鎖)
1.1 多個執行緒對同乙個資料進行修改時,可能會出現不可預料的情況.2.1 例項化物件方式實現執行緒鎖 import threading 銀行存錢和取錢 def add lock global money 宣告money為全域性變數 for i in range 1000000 2.操作變數之前進行...
多執行緒的幾種鎖
所有鎖的前提是 synchronized 條件下 重入鎖 執行緒1 執行方法a,方法a中執行方法b,則產生重入鎖,即不需要等待獲取鎖 中斷鎖 reentrantlock 使用synchronized修飾的方法,在阻塞狀態blocked時不能被外部打斷,除非jvm報錯.使用reentrantlock中...