并发编程-锁

两种上下文环境

上下文分为中断上下文和进程上下文。自旋锁广泛应用于中断理部分

同步和互斥区别:

  1. 互斥实际上资源的排他使用,同步目的时多个线程协同完成同一个任务。
  2. 互斥量只能为0或1, 信号量可以为非负整数
  3. 互斥量加锁和解锁必须是同行一个线程,信号量可以是一个线程释放,一个线程得到

悲观锁

通常有以下两种锁

  • 共享锁【shared locks】又称为读锁,简称 S 锁。顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。
  • 排他锁【exclusive locks】又称为写锁,简称 X 锁。顾名思义,排他锁就是不能与其他锁并存,如果一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁。获取排他锁的事务可以对数据行读取和修改

乐观锁

乐观锁是相对悲观锁而言的,乐观锁假设数据一般情况不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果冲突,则返回给用户异常信息,让用户决定如何去做。乐观锁适用于读多写少的场景,这样可以提高程序的吞吐量。

常见实现 version, cas

信号量

目的实现进程或线程间同步

互斥锁

   线程间资源共享 获取不到资源时进入内核休眠状态,会引起进程上下文切换,适合于需要长时间持有锁的情况。

CAS(compare and swap)

乐观锁的一种,也叫自旋锁。lock free(无锁编程)的一种实现。本身是原子操作。不会引起进程上下文切换。比互斥锁效率高很多。适合于获取锁时间很短的情况,可以高效的解决原子操作。编程实现如下:

int compare_and_swap (int* reg, int oldval, int newval) {

  ATOMIC();

  int old_reg_val = *reg;

  if (old_reg_val == oldval)

  *reg = newval;

  END_ATOMIC();
 
  return old_reg_val;

}

cas无法解决如下问题:

  • ABA:

        cas中判断当前值和老值相等时,当前值已经变成其他值又变回了老值,此时实际上已经变化了不应该cas成功。要解决该问题可以加变量包装成一个复合属性,除了值本身外再增加一个version号,每次改变时除了变量本身的值外version+1,类似数据的乐观锁。

  • 长时间获取锁造成cpu资源浪费

死锁

系统资源不足多个进程出现的环路等待。如执行的函数枷锁后被递归调用函数自身或递归获取相同锁。解决死锁问题的常用方法:

  • 资源一次性分配:一次性分配所有资源,这样就不会再有请求了:(破坏请求条件)
  • 只要有一个资源得不到分配,也不给这个进程分配其他的资源:(破坏请保持条件)
  • 可剥夺资源:即当某进程获得了部分资源,但得不到其它资源,则释放已占有的资源(破坏不可剥夺条件)
  • 资源有序分配法:系统给每类资源赋予一个编号,每一个进程按编号递增的顺序请求资源,释放则相反(破坏环路等待条件)
  • 超时释放

脏写

也叫丢失更新。AB两个事务同时读取了一个值,B后修改把A的修改覆盖了,造成A的更新丢失

脏读

脏读是指一个事务读取到其他事务没有提交(先修改后回滚)的数据

幻读

是指一个事务内多次根据同一条件查询出来的记录行数不一致。

不可重复读

是指一个事务内多次根据同一查询条件查询出来的同一行记录的值不一致。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值