锁的用途可以明确地分为读和写。Linux提供了专门的读-写自旋锁。这种自旋锁为读和写分别提供了不同的锁。一个或多少任务可以并发地持有读取锁;而写入锁一次最多只能被一个任务持有,而且此时不能有并发的读操作。我们可以将读/写锁分别叫做共享(并发)/排斥锁 。
读写锁的用法与一般自旋锁的用法相似。
初始化:rwlock_t mr_rwlock = RW_LOCK_UNLOCKED;
在读取的代码中:
read_lock(&mr_rwlock) ;
/*临界区*/
read_unlock(&mr_rwlock);
在写入的代码中:
write_lock(&mr_rwlock);
/*临界区*/
write_unlock(&mr_rwlock);
通常情况下,读锁与写锁是分开写的。注意不能将一个读锁“Update”为写锁,如下面的代码将导致死锁
read_lock(&mr_rwlock);
write_lock(&mr_rwlock);
因为写锁要不断自旋,等待所有的读锁释放锁,当然也就包括它自己,但是它自己处在忙循环等待中,不能释放锁。所以当需要写操作时,一开始就应该请求写锁,要么先释放读锁,然后再申请写锁。
Linux 提供的读写自旋锁的方法如下:
read_lock() 获得指定的读锁
read_lock_irq() 禁止本地中断并获得指定的读锁
read_lock_irqsave()存储本地中断的当前状态,禁止本地中断并获得指定读锁
read_unlock() 释放指定的读锁
read_unlock_irq()释放指定的读锁并激活本地中断
read_unlock_irqrestore()释放指定的读锁并将本地中断恢复到指定的前状态
write_lock() 获得指定的写锁
write_lock_irq() 禁止本地中断并获得指定的写锁
write_lock_irqsave()存储本地中断的当前状态,禁止本地中断并获得指定写锁
write_unlock() 释放指定的写锁
write_unlock_irq()释放指定的写锁并激活本地中断
write_unlock_irqrestore()释放指定的写锁并将本地中断恢复到指定的前状态
writ_trylock() 试图获得指定的写锁,如果写锁不可用,返回非0值
rw_lock_init()初始化指定的rwlock_t
rw_is_locked() 如果指定的锁当前已被持有,返回非0值,否则返回0
如果写和读不能清楚分开的话,那么最好就使用一般的自旋锁