自旋锁和读写锁

编程入门 行业动态 更新时间:2024-10-25 22:26:54

自旋锁和读写锁

自旋锁和读写锁

自旋锁概念

        ​何谓自旋锁?它是为实现保护共享资源而提出一种锁机制。其实,自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用。无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。但是两者在调度机制上略有不同。对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,“自旋”一词就是因此而得名。

自旋锁_百度百科 (baidu)/%E8%87%AA%E6%97%8B%E9%94%81/9137985?fr=ge_ala        

        对于自旋锁来说,它只需要消耗很少的资源来建立锁;随后当线程被阻塞时,它就会一直重复检查看锁是否可用了,也就是说当自旋锁处于等待状态时它会一直消耗CPU时间。

        对于互斥锁来说,与自旋锁相比它需要消耗大量的系统资源来建立锁;随后当线程被阻塞时,线程的调度状态被修改,并且线程被加入等待线程队列;最后当锁可用时,在获取锁之前,线程会被从等待队列取出并更改其调度状态;但是在线程被阻塞期间,它不消耗CPU资源。

        因此自旋锁和互斥锁适用于不同的场景。自旋锁适用于那些仅需要阻塞很短时间的场景,而互斥锁适用于那些可能会阻塞很长时间的场景。

自旋锁相关api

#include <pthread.h>
//创建锁
pthread_spinlock_t spinlock_t;
//初始化自旋锁
int pthread_spin_init(pthread_spinlock_t *lock, int pshared);
//销毁自旋锁
int pthread_spin_destroy(pthread_spinlock_t *lock);
//加锁
int pthread_spin_lock(pthread_spinlock_t *lock);
//解锁
int pthread_spin_unlock(pthread_spinlock_t *lock);
//非阻塞
int pthread_spin_trylock(pthread_spinlock_t *lock);

pshared取值:
        PTHREAD_PROCESS_SHARED:该自旋锁可以在多个进程中的线程之间共享。(可以被其他进程中的线程看到)
        PTHREAD_PROCESS_PRIVATE:仅初始化本自旋锁的线程所在的进程内的线程才能够使用该自旋锁

读写锁概念

        读写锁实际是一种特殊的自旋锁,它把对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则需要对共享资源进行写操作。

        如果读写锁当前没有读者,也没有写者,那么写者可以立刻获得读写锁,否则它必须自旋在那里,直到没有任何写者或读者。如果读写锁没有写者,那么读者可以立即获得该读写锁,否则读者必须自旋在那里,直到写者释放该读写锁。

读写锁_百度百科 (baidu)/%E8%AF%BB%E5%86%99%E9%94%81/1756708?fr=ge_ala

读写锁相关api

//初始化锁
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);
//销毁锁
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
//获取读锁
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
//获取写锁
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
//释放锁
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
//非阻塞获取
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);

自旋锁代码示例

#include <stdio.h>
#include <pthread.h>pthread_spinlock_t spin;void *func1()
{int i;pthread_spin_lock(&spin);for(i=0;i<5;i++){printf("t1 id:%ld\n",(unsigned long)pthread_self());}printf("========================\n");pthread_spin_unlock(&spin);
}void *func2()
{pthread_spin_lock(&spin);printf("t2 id:%ld\n",(unsigned long)pthread_self());pthread_spin_unlock(&spin);
}
void *func3()
{pthread_spin_lock(&spin);printf("t3 id:%ld\n",(unsigned long)pthread_self());pthread_spin_unlock(&spin);
}int main()
{pthread_t t1;pthread_t t2;pthread_t t3;pthread_spin_init(&spin,PTHREAD_PROCESS_SHARED);pthread_create(&t1, NULL, func1,NULL);pthread_create(&t2, NULL, func2,NULL);pthread_create(&t3, NULL, func3,NULL);pthread_join(t1,NULL);pthread_join(t2,NULL);pthread_join(t3,NULL);pthread_spin_destroy(&spin);return 0;
}

编译运行可以看到 func1运行5次放锁后 t2和t3才运行

更多推荐

自旋锁和读写锁

本文发布于:2023-12-06 00:56:52,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1665943.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!