- 读者-写者问题
允许多个线程同时对数据进行读操作,但是不允许读和写以及写和写操作同时发生。
Semaphore 是 python 中的信号量,其内部维护着一个计数器,值为一个非负整数。
对该信号量调用 acquire() 方法,如果内部计数器值为 0 ,则当前线程阻塞;如果大于 0 ,则会减一。
调用 release() 方法,则将计数器值加一,并唤醒阻塞的线程
举个例子
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))
- 代码
实现思路是我在 github 项目 CS-Notes 中看来的,可以去那里看详细说明
import threading
import time
# 其实用 Lock 也可以实现
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()