目录:
1 读写锁
前言
在阅读《高性能的MySQL》第一章时,提及到了 MySQL 的并发控制,其最基本的实现原理就是读写锁,那么如何实现一个读写锁呢?下面是一个教科书版本的读写问题描述:
一个数据文件或记录可被多个进程共享,允许多个进程同时读一个共享对象,因为读操作不会使数据文件混乱,不允许写进程与其他读进程或写进程同时访问共享对象,因为这种访问会引起混乱。
信号量机制解决读者写者问题
设置一个读写进程互斥信号量 Wmutex
,设置一个整形变量 Readcount
表示正在读的进程数目。只要有一个 Reader 进程在读,便不允许 Writer 进程去写。仅当,Readercount=0
,表示尚无 Reader 进程在读时,Reader 进程执行 Wait(Wmutex)
操作,防止写进程操作,为释放资源做准备。若 wait(Wmutex)
操作成功,Reader 进程便进行读操作, Readercount+1
。同理,当 Reader 进程在执行了 Readercount-1
后其值为 0 时,才需执行 signal(Wmutex)
操作,以便让 Write 进程写操作。又因为 Readercount
是一个可被多个 Reader 进程访问的临界资源,因此设置一个互斥信号量 rmutex
。
读写锁模拟
这里利用了 Python 的线程来进行了算法实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| import threading import time class ReadWriteLock(object): def __init__(self): self.w_lock = threading.Lock() self.r_lock = threading.Lock() self.read_count = 0 def acquire_read(self): self.r_lock.acquire(blocking=True) if self.read_count == 0: self.w_lock.acquire() self.read_count += 1 self.r_lock.release() print(self.read_count) def release_read(self): self.r_lock.acquire(blocking=True) self.read_count -= 1 if self.read_count == 0: self.w_lock.release() self.r_lock.release() def acquire_write(self): self.w_lock.acquire(blocking=True) def release_write(self): self.w_lock.release() rw_lock = ReadWriteLock() class ReadThread(threading.Thread): def __init__(self): threading.Thread.__init__(self) self.rw_lock = rw_lock def run(self): while True: try: rw_lock.acquire_read() print(u"Thread %s is reading..." % self.name) time.sleep(2) finally: rw_lock.release_read() class WriteThread(threading.Thread): def __init__(self): threading.Thread.__init__(self) self.rw_lock = rw_lock def run(self): while True: try: rw_lock.acquire_write() print(u"Thread %s is writing..." % self.name) time.sleep(2) finally: rw_lock.release_write() if __name__ == '__main__': for i in range(5): read_thread = ReadThread() read_thread.start() for j in range(5): write_thread = WriteThread() write_thread.start()
|
延伸
读优先,写优先
参考
《计算机操作系统(第4版)汤小丹、汤子瀛》