In continuation of the previous text 第5章:并发与竞态条件-10:The Spinlock Functions, let's GO ahead.
Reader/Writer Spinlocks
The kernel provides a reader/writer form of spinlocks that is directly analogous to the reader/writer semaphores we saw earlier in this chapter. These locks allow any number of readers into a critical section simultaneously, but writers must have exclusive access. Reader/writer locks have a type of rwlock_t, defined in . They can be declared and initialized in two ways:
内核提供了一种读写形式的自旋锁,其功能与本章前文介绍的读写信号量(rwsem)直接类似。这类锁允许任意数量的读线程同时进入临界区,但写线程必须独占访问。读写自旋锁的类型为 rwlock_t,定义在 <linux/spinlock.h> 头文件中。它们可通过以下两种方式声明和初始化:
rwlock_t my_rwlock = RW_LOCK_UNLOCKED; /* Static way */
rwlock_t my_rwlock;
rwlock_init(&my_rwlock); /* Dynamic way */
The list of functions available should lookreasonably familiar by now. For readers, the following functions are available:
目前可用的函数列表应该看起来相当熟悉了。读线程可使用以下函数:
void read_lock(rwlock_t *lock);
void read_lock_irqsave(rwlock_t *lock, unsigned long flags);
void read_lock_irq(rwlock_t *lock);
void read_lock_bh(rwlock_t *lock);
void read_unlock(rwlock_t *lock);
void read_unlock_irqrestore(rwlock_t *lock, unsigned long flags);
void read_unlock_irq(rwlock_t *lock);
void read_unlock_bh(rwlock_t *lock);
Interestingly, there is no read_trylock. The functions for write access are similar:
有趣的是,读写自旋锁没有 read_trylock(读线程非阻塞尝试获取锁)函数。写线程的访问函数与之类似:
void write_lock(rwlock_t *lock);
void write_lock_irqsave(rwlock_t *lock, unsigned long flags);
void write_lock_irq(rwlock_t *lock);
void write_lock_bh(rwlock_t *lock);
int write_trylock(rwlock_t *lock);
void write_unlock(rwlock_t *lock);
void write_unlock_irqrestore(rwlock_t *lock, unsigned long flags);
void write_unlock_irq(rwlock_t *lock);
void write_unlock_bh(rwlock_t *lock);
Reader/writer locks can starve readers just as rwsems can. This behavior is rarely a problem; however, if there is enough lockcontention to bring about starvation, performance is poor anyway.
与读写信号量一样,读写自旋锁也可能导致读线程饥饿(即读线程长时间无法获取锁)。但这种情况通常不会构成严重问题:如果锁的竞争激烈到足以引发饥饿,系统性能本身就已经很差了。
补充说明:
-
函数核心语义
读写自旋锁的函数用法与普通自旋锁完全一致,仅区分 “读访问” 和 “写访问”—— 读函数允许多读者并发,写函数保证单写者独占,且读、写操作互斥。 -
配对使用要求
必须严格遵循 “获取 - 释放” 函数配对原则,例如read_lock_irqsave需与read_unlock_irqrestore配对,write_lock_bh需与write_unlock_bh配对,避免中断或软中断状态异常。 -
无 read_trylock 的设计考量
内核认为读线程非阻塞获取锁的需求极少,且实现该功能需处理多读者并发的原子性判断,复杂度高且收益有限,因此未提供该接口。 -
适用场景限制
仅适用于 “读操作远多于写操作、临界区极短” 的场景,且支持中断上下文、软中断上下文与进程上下文的混合使用(需通过对应带中断 / 软中断禁用的函数)。 -
饥饿问题补充
读线程饥饿的本质是 “写线程优先级高于读线程”—— 当有写线程等待时,新的读线程会被阻塞,直到所有等待的写线程完成操作。若写操作频繁,会导致读线程长期无法获取锁,此时应改用普通自旋锁。
1018

被折叠的 条评论
为什么被折叠?



