**rwsem(Read/Write Semaphore,读写信号量)**专门为了解决读多写少的并发场景。

rwsem 的规则如下:

读锁(Read Lock):允许多个进程同时持有。只要没有人在写,大家都能读。

写锁(Write Lock):是排他性的。一旦有人要写,既不允许其他人读,也不允许其他人写。

使用需要包含<linux/rwsem.h>

初始化:

1
2
struct rw_semaphore my_rwsem;
init_rwsem(&my_rwsem);

读操作:

1
2
3
down_read(&my_rwsem);    // 申请读锁,如果有人在写或写排队则睡觉
/* --- 临界区:只读操作 --- */
up_read(&my_rwsem); // 释放读锁

写操作:

1
2
3
down_write(&my_rwsem);   // 申请写锁,如果有任何人在读或写则睡觉
/* --- 临界区:写入/修改操作 --- */
up_write(&my_rwsem); // 释放写锁

上面读操作提到

如果有人在写排队则睡觉,这是为了防止写程序饿死,要读者是一个接一个不停地来,临界区里就永远至少有一个读者。写者 B 将永远等不到空闲时刻。在系统监控看来,写者 B 的 CPU 占用率为 0,任务进度为 0。

如果想实现极致写优先,即便有人在读也可以写,可以考虑使用seqlock,写者永远不会被读者阻塞,但多个写者之间仍然是互斥的(通常内部带有一个自旋锁)。也就是说,同一时间只能有一个人在写。

原理:写者增加一个序号,读者在读前后检查序号。如果序号变了,说明读期间有人写过,读者就重新读一遍。