自旋锁和读写锁

自旋锁概念

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

自旋锁_百度百科 (baidu.com)icon-default.png?t=N7T8https://baike.baidu.com/item/%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.com)icon-default.png?t=N7T8https://baike.baidu.com/item/%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才运行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值