linux 锁机制

linux 锁机制,第1张

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...

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5637258.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存