同步與異步:
同步:指一個進程在執行某個請求的時候,若該請求需要一段時間才能返回信息,那麼這個進程將會一直等待下去,直到收到返回信息才繼續執行下去。
異步:指進程不需要一直等下去,而是繼續執行下面的操作,不管其他進程的狀態。當有消息返回時系統會通知進程進行處理,這樣可以提高執行的效率。
同步是阻塞模式,異步是非阻塞模式。
我的理解:同步是指兩件事情有關聯,其中一件事情要等待另外一件事情的進行。異步的意思是兩件事情毫無關聯。
互斥鎖:
不加鎖:
代碼演示:
import threading
from threading import Thread
num = 0
def work1(n):
global num
for i in range(n):
num +=1
print("in work1:",num)
def work2(n):
global num
for i in range(n):
num += 1
print("in work2:",num)
def main():
t1 = Thread(target=work1,args=(1000000,))
t2 = Thread(target=work2,args=(1000000,))
t1.start()
t2.start()
t2.join()
if __name__ == '__main__':
main()
print("main:",num)
運行結果:
加鎖:
代碼演示:
import threading
from threading import Thread
num = 0
lock = threading.Lock() #創建一個鎖
def work1(n):
global num
lock.acquire() #加鎖
for i in range(n):
num +=1
lock.release() #解鎖
print("in work1:",num)
def work2(n):
global num
lock.acquire() #加鎖
for i in range(n):
num += 1
lock.release() #解鎖
print("in work2:",num)
def main():
t1 = Thread(target=work1,args=(1000000,))
t2 = Thread(target=work2,args=(1000000,))
t1.start()
t2.start()
t2.join()
if __name__ == '__main__':
main()
print("main:",num)
運行結果:
鎖的好處:確保了某段關鍵代碼只能由一個線程從頭到尾完整地執行。
鎖的壞處:阻止了多線程併發執行,包含鎖的某段代碼實際上只能以單線程模式執行,效率就大大地下降了由於可以存在多個鎖,不同的線程持有不同的鎖,並試圖獲取對方持有的鎖時,可能會造成死鎖。
死鎖:
死鎖就是一直等待對方釋放鎖的情景
死鎖的結果會造成程序的停止響應, 不能再處理其他的任務了
死鎖示例
代碼演示:
from threading import Lock
from threading import Thread
lock1 = Lock()
lock2 = Lock()
def work1(num):
lock1.acquire() #lock1上鎖
print("in work1")
lock2.acquire() #lock2上鎖
print("work1----")
lock2.release() #lock2解鎖
lock1.release() #lock1解鎖
def work2(num):
lock2.acquire() #lock2加鎖
print("in work2")
lock1.acquire() #lock2加鎖
print("work2-----")
lock1.release() #lock1解鎖
lock2.release() #lock2解鎖
if __name__ == '__main__':
t1 = Thread(target=work1,args=(1000000,))
t2 = Thread(target=work2,args=(1000000,))
t1.start()
t2.start()
運行結果:
避免死鎖
代碼演示:
from threading import Lock
from threading import Thread
import time
lock1 = Lock()
lock2 = Lock()
def work1(num):
lock1.acquire() #lock1上鎖
time.sleep(1)
print("in work1")
lock2.acquire() #lock2上鎖
print("work1----")
lock2.release() #lock2解鎖
lock1.release() #lock1解鎖
def work2(num):
lock2.acquire() #lock2加鎖
print("in work2")
lock1.acquire() #lock2加鎖
print("work2-----")
lock1.release() #lock1解鎖
lock2.release() #lock2解鎖
if __name__ == '__main__':
t1 = Thread(target=work1,args=(1000000,))
t2 = Thread(target=work2,args=(1000000,))
t1.start()
t2.start()
運行結果: