Chinaunix首页 | 论坛 | 博客
  • 博客访问: 179399
  • 博文数量: 11
  • 博客积分: 1410
  • 博客等级: 上尉
  • 技术积分: 355
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-28 11:20
文章分类
文章存档

2009年(6)

2008年(5)

我的朋友

分类: LINUX

2009-10-22 20:44:33

读写锁,是自旋锁的一种衍生锁,为什么要衍生锁了,是因为自旋锁在多个执行单元在同时读写临界资源时都会被锁住,这样最多只能有一个执行单元拥有锁进而对资源进行操作,然而事实并非如此,在很多时候,同时读取临界资源是没有问题的,所以引入读写锁,他解决了读执行单元同时操作临界资源的问题,即允许读并发,但在写单元执行时最多允许一个进程访问临界资源。

定义和初始化:

rwlock_t my_rwlock=RW_LOCK_UNLOCKED; //静态初始化

rwlokc_t my_rwlock;

rwlock_init(&my_rwlock); //动态初始化

读锁定与解锁

//读锁定与读解锁

void read_lock(rwlock_t *lock)

void read_unlock(rwlock_t *lock)

//相当于: read_lock()+local_irq_save()/local_irq_restore

void read_lock_irqsave(rwlock_t *lock,unsigned long flags)

void read_unlock_irqrestore(rwlock_t *lock,unsigned long flags)

//相当于:read_lock()+local_irq_disable()/local_irq_enable()

void read_lock_irq(rwlock_t *lock)

void read_unlock_irq(rwlock_t *lock)

//相当于:read_lock()+local_bh_disable()/local_bh_enable()

void read_lock_bh(rwlock_t *lock)

void read_unlock_bh(rwlock_t *lock)

写锁定与解锁:

//写锁定与写解锁

void write_lock(rwlock_t *lock)

void write_unlock(rwlock_t *lock)

//相当于: write_lock()+local_irq_save()/local_irq_restore

void write_lock_irqsave(rwlock_t *lock,unsigned long flags)

void write_unlock_irqrestore(rwlock_t *lock,unsigned long flags)

//相当于: write_lock()+local_irq_disable()/local_irq_enable()

void write_lock_irq(rwlock_t *lock)

void write_unlock_irq(rwlock_t *lock)

//相当于: write_lock()+local_bh_disable()/local_bh_enable()

void write_lock_bh(rwlock_t *lock)

void write_unlock_bh(rwlock_t *lock)


另外还有:int write_trylock(rwlock_t *lock) ,不管成功与否,都会立即返回。

一般有如下用法模型:

rwlock_t lock; //定义

read_init( &lock);

..........//临界资源

read_unlock(&lock);


//写时

write_lock_irqsave(&lock,flags);

..........//临界资源

write_unlock_irqrestroe(&lock,flags);

顺序锁(seqlock_t),对读写锁的一种优化,使用顺序锁时,读不会被写执行单元阻塞,也就是说,当向一个临界资源中写入的同时,也可以从此临界资源中读取,即实现同时读写,但是同时写不被允许。如果读执行单元在读操作期间,写执行单元已经嗯发生了写操作,那么,读执行单元必须重新开始,这样保证了数据的完整性,当然这种可能是微乎其微。顺序锁的性能是非常好的,同时他允许读写同时进行,大大的提高了并发性。

但是他有一个限制:共享资源不含有指针,因为写执行单元可能使得指针失效,但读执行单元如果正要访问该指针,将导致Oops( 网上搜索这个词的意思是:吃惊的感叹词。我理解为访问该指针将会导致意想不到的结果)

写执行单元涉及到的一些相关操作

void write_seqlock(seqlock_t *s1);

void write_sequnlock(seqlock_t *s1);


//宏调用,相当于:write_seqlock()+local_irq_save()

write_seqlock_irqsave(lock,flags)

write_sequnlock_irqrestore(lock,flags)


//宏调用,相当于:write_seqlock()+local_irq+disable()

write_seqlock_irq(lock)

write_sequnlock_irq(lock)


//宏调用,相当于:write_seqlock()+local_bh_disable()

write_seqlock_bh(lock)

write_sequnlock_bh(lock)


int write_tryseqlock(seqlock_t *s1),此函数和上面提到的类似。

写执行单元使用如下一种模式的顺序锁:

write_seqlock(&seqlock);

.........//写操作代码块

write_sequnlock(&seqlock);

读执行单元涉及如下顺序锁操作:

读开始:unsigned read_seqbegin(const seqlock_t *s1);//读执行单元在访问共享资源时要//调用该函数,返回锁s1的顺序号,

read_seqbegin_irqsave(lock,flags)  //等同于:local_irq_save()+read_seqbegin()

重读int read_seqretry(const seqlock_t *s1,unsigned iv) //在读结束后调用此函数来检///查,是否有写执行单元对资源进行操作,若有,则重新读。iv 为锁的顺序号。

代码段如下:

do{

seqnum=read_seqbegin(&seqlock);

//读操作代码段

...........

}while(read_seqretry(&seqlock,seqnum);

阅读(1301) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~