Linux下写者优先的读写锁的设计

Linux下写者优先的读写锁的设计

在 IBM Bluemix 云平台上开发并部署您的下一个应用。现在就开始免费试用

一、本文的目的在linux下有两种实现数据互斥的基本机制,包括了semaphore(信号量),spinlock(自旋锁)。这里要说的读写锁(read write lock)是自旋锁的一个变种,与一般的自旋锁的区别是,自旋锁一次只能有一个进程进入临界区,而对读写锁而言,如果进程是读的话,那就可以有多个进程同时进入临界区,而如果是写的话,则只有一个可以。就现在的linux内核源代码的发行版本而言,已经实现了读写锁的一个类型,就是读者优先的读写锁。(在这个设计中,作为读的请求可以更容易的进入临界区,而写的请求的请求往往容易受阻,这个我在后面会分析),而我要设计的读写锁,则是以写进程为优先的考虑的对象,如果有写的请求发出,则它会在被允许的最快时间内得到响应。这样的好处是在一个由很多客户端以读的权限访问的服务器(如一般的公众服务器),如果管理员对服务器的某些内容或配置进行修改的话,那它的及时性就有可能无法满足。这有时是不可以被接受的。回页首二、linux现有的读写锁状况我先来分析现在linux内核源代码中的读写锁的实现方式,这样就可以很容易的理解后面的写者优先的读写锁的设计。先介绍一个数据结

构,这是在读写锁起到重要作用。(注:下面所有的内核源代码均来自linux 2.4.17,如果与你的现有的内核源代码不同,请你作一些相应的改变就可以了,原理部分没有变化)typedef struct {

volatile unsigned int lock;

#if SPINLOCK_DEBUG

unsigned magic;

#endif

} rwlock_t;这里的magic是用于调试的,而lock就是允许可以加的读锁数。这个代码在linux/include/asm-i386/spinlock.h中定义了read_lock和write_lockstatic inline void read_lock(rwlock_t *rw) {

#if SPINLOCK_DEBUG

if (rw->magic != RWLOCK_MAGIC)

BUG();

#endif }

static inline void write_lock(rwlock_t *rw) {

#if SPINLOCK_DEBUG

__build_read_lock(rw, \

if (rw->magic != RWLOCK_MAGIC)

BUG();

#endif

__build_write_lock(rw, \

}注意这里有两个参数,一个是rw就是允许的读锁数,而后面一个参数是如果加锁失败的话,处理失败的函数。在这里真正调用的对write_lock是__build_write_lock_const或__build_write_lock_ptr,对read_lock中调用的是

__build_read_lock_const或__build_read_lock_ptr,这里的取决因素是调用参数的操作指令寻址方式。我们这里只看const类 #define __build_write_lock_const(rw, helper)

asm

volatile(LOCK \ \ \ \ \ \ \helper \ \ \ \ :\这里的RW_LOCK_BIAS_STR就是 \,取这个值的原因是这个值足够大,可以使满足读的请求足够多。在\

\

联系客服:779662525#qq.com(#替换为@) 苏ICP备20003344号-4