IMX6ULL嵌入式Linux驱动开发学习
以下内容是我在学习正点原子IMX6ULL
开发板alpha
中记录的笔记,部分摘录自正点原子IMX6ULL开发手册
。
Linux并发与竞争
一、并发与竞争
多线程对共享资源同时进行访问,比如全局变量,就会产生并发与竞争现象。以打印机为例,当线程A和线程B同时操作打印机时,就会出现竞争现象,如果没有处理就会导致数据错乱。
二、原子操作atomic
对整形变量或者位进行保护,确保对其进行操作时是最小操作,不会被干扰。
1 | typedef struct { |
原子操作API
函数
1 | AIOMIC_INIT(int i) // 定义原子变量的时候对其初始化 |
三、原子位操作
原子位操作不像原子整形变量那样有个atomic_t
的数据结构,原子位操作是直接对内存进行操作。
API
函数如下
1 | void set_bit(int nr, void* p) // 将p地址的第nr位置1 |
四、自旋锁spinlock
- 用于多核
SMP
。 - 适合短时间加锁,轻量级加锁。
- 自旋锁会自动禁止抢占。
- 使用自旋锁,要注意死锁现象的发生,被自旋锁保护的临界区一定不能调用任何能够引起睡眠和阻塞的
API函数
。(线程与线程中之间,线程与中断之间)。
API
函数
1 | spinlock_t lock; // 定义自旋锁 |
使用示例:
1 | DEFINE_SPINLOCK(lock) // 定义并初始化一个锁 |
五、信号量semaphore
- 信号量可以使等待资源线程进入休眠状态,因此适用于占用资源比较久的场合。
- 信号量不能用于中断中,因为信号量会引起休眠,中断不能休眠。
- 信号量会将等待信号量中休眠的线程唤醒。
- 如果共享资源的持有时间比较短,那就不适合适用信号量了。
API
函数
1 | DEFINE_SEAMPHORE(name) // 定义一个信号量,并且设置信号量的值为1 |
使用方式如下:
1 | struct semaphore sem; // 定义信号量 |
六、互斥锁mutex
- 互斥体可以导致休眠,因此不能在中断中使用,中断中只能使用自旋锁。
- 互斥体保护的临界区可以调用引起阻塞的
API函数
。 - 一次只有一个线程可以持有互斥体,因此必须由
mutex
的持有者释放mutex
。不能递归上锁和解锁。
API
函数:
1 | DEFINE_MUTEX(name) // 定义并初始化一个 mutex 变量。 |
使用示例:
1 | struct mutex lock; // 定义一个互斥体 |
- 本文作者: 路痴的兔子
- 本文链接: https:/proudrabbit.gitee.io/IMX6ULL嵌入式Linux驱动学习笔记(七).html
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!