并发锁

1.互斥锁

sleep waiting 获取锁失败 由内核调度进入休眠态。等待内核的通知,重新唤醒执行。由于进入了睡眠态,导致操作系统进行了线程的切换(有一定的开销 要保存线程的运行环境等)
特定:获取锁失败 会陷入睡眠 适用于互斥代码执行时间较长

1.1pthread_mutex_lock

pthread_mutex_lock(&mxlock);
++val;
pthread_mutex_unlock(&mxlock);

1.2pthread_mutex_trylock

好处就是不用阻塞 无论是自旋锁还是互斥锁 都立刻返回 用户可以在这期间执行其他操作

pthread_mutex_trylock 
    while(pthread_mutex_trylock(&mxlock) != 0){
        printf("pthread_mutex_trylock fail thread:%d\n",pthread_self());
    }
    ++val;
    printf("i=:%d\n",val);
    pthread_mutex_unlock(&mxlock);

2.自旋锁

busy waiting 通过CAS原子操作实现,加锁失败一直while 循环,直到获取锁成功。不会发生线程的切换。对于单核CPU,CPU必须是抢占式的(时间片用完切换)否则用自旋锁会导致这个CPU一直背占用
特定:一直占用CPU 适用于互斥代码执行时间较短,

pthread_spin_lock(&spinlock);
++val;
pthread_spin_unlock(&spinlock);

3.读写锁

保证读并发,写互斥。获取锁失败进入睡眠(互斥锁类似)

3.1 读优先:

A线程读获取到锁,B线程写获取锁失败则等待,C读 获取锁成功。 可能造成写线程饥饿,一直有读请求到来,导致写获取不到锁。

3.2写优先

A线程读获取到锁,B线程写获取锁失败则等待,C读 获取锁失败,A释放锁唤醒B线程(写锁)。 可能造成读饥饿

3.3公平锁

读写操作入队列,按顺序获取锁,保证了读并发 解决了饥饿问题

// 设置读优先
pthread_rwlockattr_setkind_np(&rwlock,PTHREAD_RWLOCK_PREFER_READER_NP); 
pthread_rwlock_wrlock(&rwlock);
++val;
pthread_rwlock_unlock(&rwlock);

4.悲观锁

多线程下,共享资源容易发生冲突,在访问之前加锁。互斥锁 自旋锁 读写锁 都是属于悲观锁

5.乐观锁

多线程下,共享资源很少发生冲突,先修改资源,修改后进行验证是否发生冲突,冲突了则放弃操作、重试。乐观锁一般叫无锁编程。虽然乐观锁无锁,但是增加了重试的成本,只有冲突概率小 加锁成本高的场景才适用。

6.CAS

compare and swap, 通过CPU的硬件指令完成互斥资源的原子操作。

参考:https://zhuanlan.zhihu.com/p/246114725

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值