C++自旋锁读写锁可重入锁与不可重入锁的简单理解

Posted 一只当归

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++自旋锁读写锁可重入锁与不可重入锁的简单理解相关的知识,希望对你有一定的参考价值。

自旋锁(spinlock):当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。
获取锁的线程一直处于活跃状态,但是并没有执行任何有效的任务,使用这种锁会造成忙等busy-waiting,消耗CPU资源。
在之前的博客中,我们了解过互斥锁,互斥锁实际上是一种sleep-waiting的锁,当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将被阻塞放入等待队列,不会造成忙等现象,CPU可以去处理其他任务,不会浪费CPU资源。

//自旋锁互斥实现
class spinlock_mutex

    std::atomic_flag flag;
public:
    spinlock_mutex():flag(ATOMIC_FLAG_INIT) 
    void lock()

    while(flag.test_and_set(std::memory_order_acquire));

    void unlock()

    flag.clear(std::memory_order_release);


读写锁(readers-writer lock):读写锁可以和读者-写者问题结合起来理解,读写锁是一种特殊的自旋锁,它把对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则可以对共享资源进行写操作。简单来说就是一次只能有一个人写,但可以多个人一起读。
当读写锁被加了写锁时,其他线程对该锁加读锁或写锁都会被阻塞;当读写锁被加了读锁时,其他线程对该锁加读锁会成功,加写锁会被阻塞。比较适用于多读少写的场景。
可重入锁(reentrant lock):
可重入锁简单如字面而言,就是可以重新进入的锁,允许同一进程多次获取同一把锁,是可重复可递归调用的锁,在外层使用锁之后,在内层仍然可以使用,并且不发生死锁(前提是同一个对象或者class),这样的锁就叫做可重入锁,也叫做递归锁。

不可重入锁(non-reentrant lock):
不可重入锁与可重入锁相反,如果当前线程已经获取了该锁,那么再次尝试获取该锁时,就会出现死锁的状况,被阻塞。在这个线程解锁之前,其他线程无法用这个锁再来加锁。

可重入锁不与可重入锁的区别:不可重入锁只判断这个锁有没有被锁上,只要被锁上申请锁的线程都会被要求等待。实现起来较为简单。而可重入锁不仅要判断锁有没有被锁上,还会判断锁是谁锁上的,当就是自己锁上的时候,那么他依旧可以再次访问临界资源,并把加锁次数加一。

以上是关于C++自旋锁读写锁可重入锁与不可重入锁的简单理解的主要内容,如果未能解决你的问题,请参考以下文章

通俗易懂 悲观锁乐观锁可重入锁自旋锁偏向锁轻量/重量级锁读写锁各种锁及其Java实现!

通俗易懂 悲观锁乐观锁可重入锁自旋锁偏向锁轻量/重量级锁读写锁各种锁及其Java实现!

Java 中15种锁的介绍:公平锁,可重入锁,独享锁,互斥锁,乐观锁,分段锁,自旋锁等等(转)

zbb20180929 thread 自旋锁阻塞锁可重入锁悲观锁乐观锁读写锁对象锁和类锁

Java 独占锁与共享锁公平锁与非公平锁可重入锁

自旋锁阻塞锁可重入锁悲观锁乐观锁读写锁偏向所轻量级锁重量级锁锁膨胀对象锁和类锁