linux 锁机制

1. 锁的种类

Name函数api特点
原子操作

atomic_read

atomic_set

只能针对单变量
信号量/互斥锁

down

down_interruptible

down_uninterruptible

up
一般当获取不到当前的锁变量时会进入睡眠,不能在中断上下文中使用
自旋锁

spin_lock

spin_unlock

捕获不到当前锁变量时,会一直死等,不会睡眠,需要保证获取锁当中的代码不耗时,不睡眠
读写锁

read_lock/read_unlock

write_lock/write_unlock

支持多个读进程并存,但是读和写进程是互斥的
RCU

rcu_read_lock/rcu_dereference/rcu_read_unlock

rcu_assign_pointer

读写操作可以并存

2. 自旋锁

自旋锁可以使用在中断上下文中,但是使用时候需要一些技巧。

场景1: 进程和中断互斥的情况

//进程
int process_func()
{
    spin_lock(xx)
    a++
    spin_unlock(xx)
}

//中断
int interrupt_handler()
{
    spin_lock(xx)
    a++
    spin_unlock(xx)
}    

问题:当process_func已经获取锁,这时候发生了中断(中断是可以打断进程的),这时候就会进入interrupt_handler,但这时候无法获取锁,因为锁已经被进程process_func获取,这时候就会导致中断处理函数无法返回,系统死锁。

解决办法:就是需要在进程上下文中,关中断,然后获取spin_lock

//进程
int process_func()
{
    //先关中断,再获取锁
    spin_lock_irq(xx)
    a++
    //释放锁,开中断
    spin_unlock_irq()
}

//中断
int interrupt_handler()
{
    spin_lock(xx)
    a++
    spin_unlock(xx)
}    

场景2: 函数嵌套调用

//进程A
int process_funcA()
{
    //先关中断,再获取锁
    spin_lock_irq(xxA)
    process_funcB()
    a++
    //释放锁,开中断
    spin_unlock_irq(xxA)
}

//进程B
int process_funcB()
{
    //先关中断,再获取锁
    spin_lock_irq(xxB)
    a++
    //释放锁,开中断
    spin_unlock_irq(xxB)
}

//中断
int interrupt_handler()
{
    spin_lock(xxA)
    a++
    spin_unlock(xxA)
}    

问题: 进程A虽然已经关掉了中断,但是调用B之后,又开了中断,执行a++之前,如果被中断interrupt_handler打断,那么又会死锁。

解决方法:

//进程A
int process_funcA()
{
    //先保存中断标志,再关中断,再获取锁
    spin_lock_irqsave(xxA)
    process_funcB()
    a++
    //释放锁,回复保存的中断标志
    spin_unlock_irqrestore(xxA)
}

//进程B
int process_funcB()
{
    //先保存中断标志,再关中断,再获取锁
    spin_lock_irqsave(xxB)
    a++
    //释放锁,回复保存的中断标志
    spin_unlock_irqrestore(xxB)
}

//中断
int interrupt_handler()
{
    spin_lock(xxA)
    a++
    spin_unlock(xxA)
}    

others

todo...

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值