[TOC]
一、鎖
線程中的鎖機制和進程中一樣。都是通過鎖來控制資源訪問雖然,線程中的資源是共享的,但也可以通過鎖來進行控制。達到線程同步的目的。雖然犧牲了效率但是保證了安全。
x = 0
mutex = Lock()
def task():
global x
mutex.acquire() # 上鎖
for i in range(200000):
x = x +1
mutex.release() # 解鎖
if __name__ == '__main__':
th_list = []
for i in range(10):
t1 = Thread(target=task())
t1.start()
th_list.append(t1)
for i in th_list:
i.join()
print(x)
二、解決死鎖問題---遞歸鎖
**死鎖問題:**死鎖就是A等B,B等A,互相都在等鎖的開啟。因此會造成阻塞。
from threading import Thread,Lock,RLock
# 普通的鎖,會出現死鎖問題
mutex1 = Lock()
mutex2 = Lock()
import time
class MyThread(Thread):
def run(self):
self.task1()
self.task2()
def task1(self):
mutex1.acquire()
print(f'{self.name} 搶到了 鎖1 ')
mutex2.acquire()
print(f'{self.name} 搶到了 鎖2 ')
mutex2.release()
print(f'{self.name} 釋放了 鎖2 ')
mutex1.release()
print(f'{self.name} 釋放了 鎖1 ')
def task2(self):
mutex2.acquire()
print(f'{self.name} 搶到了 鎖2 ')
time.sleep(1) # 出現死鎖問題。因為沒有執行完,但是mutex1在別的線程中被上鎖。mutex2在當前線程中被上鎖。
mutex1.acquire()
print(f'{self.name} 搶到了 鎖1 ')
mutex1.release()
print(f'{self.name} 釋放了 鎖1 ')
mutex2.release()
print(f'{self.name} 釋放了 鎖2 ')
for i in range(3):
t = MyThread()
t.start()
2.1 遞歸鎖
遞歸鎖 同一個線程內可以被多次acquire,但acquire了幾次就要release幾次內部相當于維護了一個計數器
# 遞歸鎖,可以多次,多次解鎖
mutex1 = RLock()
mutex2 = mutex1
import time
class MyThread(Thread):
def run(self):
self.task1()
self.task2()
def task1(self):
mutex1.acquire()
print(f'{self.name} 搶到了 鎖1 ')
mutex2.acquire()
print(f'{self.name} 搶到了 鎖2 ')
mutex2.release()
print(f'{self.name} 釋放了 鎖2 ')
mutex1.release()
print(f'{self.name} 釋放了 鎖1 ')
def task2(self):
mutex2.acquire()
print(f'{self.name} 搶到了 鎖2 ')
time.sleep(1) # 出現死鎖問題。因為沒有執行完,但是mutex1在別的線程中被上鎖。mutex2在當前線程中被上鎖。
mutex1.acquire()
print(f'{self.name} 搶到了 鎖1 ')
mutex1.release()
print(f'{self.name} 釋放了 鎖1 ')
mutex2.release()
print(f'{self.name} 釋放了 鎖2 ')
for i in range(3):
t = MyThread()
t.start()
三、信號量
信號量就是加了計數器的鎖
代表了同時可以有 多少人 在使用鎖
from threading import Thread,currentThread, Semaphore
import time
def task():
sem.acquire()
print(f'{currentThread().name} 在執行')
time.sleep(3)
sem.release()
sem = Semaphore(5)
for i in range(15):
t = Thread(target=task)
t.start()
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
