- 讀者-寫者問題
允許多個線程同時對數(shù)據(jù)進行讀操作砾嫉,但是不允許讀和寫以及寫和寫操作同時發(fā)生拄显。
Semaphore 是 python 中的信號量,其內(nèi)部維護著一個計數(shù)器,值為一個非負整數(shù)庵寞。
對該信號量調(diào)用 acquire() 方法,如果內(nèi)部計數(shù)器值為 0 薛匪,則當前線程阻塞皇帮;如果大于 0 ,則會減一蛋辈。
調(diào)用 release() 方法属拾,則將計數(shù)器值加一,并喚醒阻塞的線程
舉個例子
import threading
a = threading.Semaphore(3)
print('a 的值: {}'.format(a._value))
for i in range(1, 4):
a.acquire()
print('第 {} 次 acquire : {}'.format(i, a._value))
a.release()
print('release: {}'.format(a._value))
- 代碼
實現(xiàn)思路是我在 github 項目 CS-Notes 中看來的冷溶,可以去那里看詳細說明
import threading
import time
# 其實用 Lock 也可以實現(xiàn)
service = threading.Semaphore(1) # 決定哪個線程拿到資源鎖
source_access = threading.Semaphore(1) # 資源鎖
count = threading.Semaphore(1) # read_count 鎖
read_count = 0
def read():
global read_count
while True:
service.acquire()
count.acquire()
if read_count == 0:
source_access.acquire()
read_count += 1
service.release()
count.release()
print('read', threading.get_ident())
time.sleep(1)
count.acquire()
if read_count == 1:
source_access.release()
read_count -= 1
count.release()
def write():
while True:
service.acquire()
source_access.acquire()
service.release()
print('write', threading.get_ident())
time.sleep(1)
source_access.release()
def read_write():
read_threads = [threading.Thread(target=read) for i in range(3)]
write_threads = [threading.Thread(target=write) for i in range(3)]
for t in read_threads + write_threads:
t.start()
if __name__ == '__main__':
read_write()