前一篇文章分析了Windows slim read/write lock的工作原理。我们知道它的设计相当精妙,于是我们可以借鉴它的思路来设计linux下的读写锁。
在这个读写锁的设计上,需要注意的是linux和windows有以下几点区别:
(1)windows使用的keyedevent机制需要使用linux下的机制代替。这里我们选用futex机制来模拟。linux下的futex机制对外表现为下面这个接口:
int futex(int *uaddr, int op, int val, const struct timespec *timeout, int *uaddr2, int val3)
但是由于没有公开提供该接口,所有我们需要使用syscall来调用它,如下:
#define futex(addr1, op, val, rel, addr2, val3) \
syscall(SYS_futex, addr1, op, val, rel, addr2, val3)
#define futex_wait_always(addr1) \
syscall(SYS_futex, addr1, FUTEX_WAIT, *(int*)(addr1), 0, 0, 0)
#define futex_wake_single(addr1) \
syscall(SYS_futex, addr1, FUTEX_WAKE, 1, 0, 0, 0)
在这里我们主要使用单个线程死等和唤醒单个线程两项操作。关于futex的其他知识可以参考搜索引擎,不再赘述。
(2)futex的wake机制和KeyedEvent有所区别。NtReleaseKeyedEvent唤醒等待线程时,如果此时尚不存在等待者,Nt