python 实现读者-写者问题

  • 读者-写者问题
    允许多个线程同时对数据进行读操作,但是不允许读和写以及写和写操作同时发生。

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()

你可能感兴趣的:(python 实现读者-写者问题)