读写自旋锁的使用用法类似于普通的自旋锁:
DEFINE_RWLOCK(mr_rwlock);read_lock(&mr_rwlock);/*critical region, only for read*/read_unlock(&mr_rwlock);write_lock(&mr_lock);/*critical region, only for write*/write_unlock(&mr_lock);注意:如果写和读不能清晰地进行分离,那么使用一般的自旋锁就够了,不需要使用读写自旋锁。 4、信号量信号量也是一种锁,和自旋锁不同的是,线程获取不到信号量的时候,不会像自旋锁一样循环去试图获取锁,而是进入睡眠,直至有信号量释放出来时,才会唤醒睡眠的线程,进入临界区执行。
由于使用信号量时,线程会睡眠,所以等待的过程不会占用 CPU 时间。所以信号量适用于等待时间较长的临界区。
信号量消耗CPU时间的地方在于使线程睡眠和唤醒线程--两次明显的上下文切换。
如果(使线程睡眠 + 唤醒线程)的 CPU 时间 > 线程自旋等待 CPU 时间,那么可以考虑使用自旋锁。 信号量有二值信号量和计数信号量两种,其中二值信号量比较常用。 二值信号量表示信号量只有2个值,即0和1。信号量为1时,表示临界区可用,信号量为0时,表示临界区不可访问。所以也可以称为互斥信号量。 计数信号量有个计数值,比如计数值为5,表示同时可以有5个线程访问临界区。所以二值信号量就是计数等于1的计数信号量。 5、读写信号量读写信号量和信号量的关系与读写自旋锁和自旋锁的关系差不多。 读写信号量都是二值信号量,即计数值最大为1,增加读者时,计数器不变,增加写者,计数器才减一。
也就是说读写信号量保护的临界区,最多只有一个写者,但可以有多个读者。 6、互斥 互斥体(mutex)也是一种可以睡眠的锁,相当于二值信号量,只是提供的API更加简单,使用的场景也更严格一些,如下所示: