• 解决驱动开发中并发和竞争中的问题----------自旋锁


    什么是自旋锁

    是指临界区资源被持有锁线程A拥有的时候,别的线程B只能原地等待不会进入睡眠,直到A释放锁,那么A才可以访问临界区资源

    注意:自旋锁一般是用在等待时间比较短的地方,如果等待时间较长的话一般考虑使用信号量

    结构体:spinlock_t

    在这里插入图片描述

    相关API函数

    下面的API是不考虑中断情况下的
    在这里插入图片描述
    主要是下面两个函数

    获得锁函数 void spin_lock(spinlock_t *lock) 获取指定的自旋锁,也叫做加锁

    解锁函数 void spin_unlock(spinlock_t *lock) 释放指定的自旋锁

    注意:上面的自旋锁API函数适用于SMP或支持抢占的单CPU下线程之间的并发访问, 也就是用于线程与线程之间(不考虑中断),被自旋锁保护的临界区一定不能调用任何能够引起睡眠和阻塞的 API 函数,否则的话会可能会导致死锁现象的发生

    注意发生死锁:
    由于获得锁之后内核会自动禁止抢占,如果线程A进入睡眠的话就相当于放弃了CPU,那么此时B线程就会运行,此时B也想获得锁,但是线程A并没有释放掉锁,并且A由于禁止抢占式不能被唤醒,所以B只能在外面等待,所以就出现死锁

    考虑中断的情况
    如果线程之间来了个中断,又会是什么情况呢
    在这里插入图片描述
    线程 A 先运行,并且获取到了 lock 这个锁,当线程 A 运行程序的时候中断发生了,中断抢走了CPU 使用权。右边的中断服务函数也要获取 lock 这个锁, 但是这个锁被线程 A 占有着,中断就会一直自旋,等待锁有效。但是在中断服务函数执行完之前,线程 A 是不可能执行的,线程 A 说“你先放手”,中断说“你先放手”,场面就这么僵持着,死锁发生!

    最好的解决方法就是获取锁之前关闭本地中断

    即调用下面的函数获得锁即可
    在这里插入图片描述

    使用自旋锁一般步骤

    在这里插入图片描述
    在这里插入图片描述

    注意事项:

    在这里插入图片描述

    总结:
    1)自旋锁的使用可以在中断中,如果有中断的话必须使用考虑中断的API获得锁,不然会出现死锁,
    2)自旋锁必须是等待时间比较短,因为自旋锁会一直占用CPU,如果需要等待长时间即进入睡眠的话那就考虑信号量,下面一篇介绍信号量
    3)自旋锁不能使用睡眠或阻塞的相关函数

  • 相关阅读:
    免费发布web APP的四个途径(Python和R)
    猿创征文|【FreeSwitch开发实践】使用sipp对FreeSwitch进行压力测试
    Codeforces 1750A. Indirect Sort
    Java基础27,28(多线程,ThreadMethod ,线程安全问题,线程状态,线程池)
    王坚院士:云计算与 GPT 的关系,就是电和电动机的关系
    【大学英语视听说上】Topic Presentation
    S0003-Mac下iTerm2+zsh+ohmyzsh打造优雅美观终端
    【无人机】基于Matlab模拟无人机群跟踪固定目标
    HashSet和LinkedHashSet
    英语——分享篇——每日200词——2601-2800
  • 原文地址:https://blog.csdn.net/qq_24093081/article/details/127125709