Linux设备驱动中的并发

简介: 并发就是多个执行单元或多个进程并行执行,而这多个执行单元对资源进行共享,比如访问同一个变量或同一个硬件资源,这个时候就很容易出现竞态(说简单点就是竞争同一个"女朋友")。

一、什么是并发

并发就是多个执行单元或多个进程并行执行,而这多个执行单元对资源进行共享,比如访问同一个变量或同一个硬件资源,这个时候就很容易出现竞态(说简单点就是竞争同一个"女朋友")。

二、如何处理并发带来的问题

为了处理并发带来的问题,Linux有几种处理方法:
1. 中断屏蔽
2. 原子操作
3. 自旋锁
4. 信号量
5. 互斥体
6. 完成量

以上几种处理并发的方式各有利弊,需要根据实际情况来选择使用哪一种。

三、并发处理方法介绍

  • 中断屏蔽

使用方法:

 local_irq_disable()  //屏蔽中断
 .......
 代码
 .......
 local_irq_enable()  //开启中断

它的原理就是让CPU不响应中断,一般使用这种方法的要求代码段要比较少,不能占用大量的时间。一般在驱动中不推荐使用这种方式。

  • 原子操作

使用方法:

atomic v = ATOMIC_INIT(1); //定义原子量,初值为1

//如果原子量减1后为0就返回true
if(atomic_dec_and_test(&v)){ 
    ....
    代码
    ...
    atomic_inc(v); //原子量加1
}else{
    atomic_inc(v);
}

原子量保证对一个整形数据的操作是排他性的。就是该操作绝不会在执行完毕前被任何其他任务或事件打断

  • 自旋锁

使用方法:

spinlock_t lock = SPIN_LOCK_UNLOCKED; //初始化自旋锁
spinlock(&lock); //获取自旋锁
....
代码
....
spin_unlock(&lock);    //释放自旋锁

自旋锁是一种典型的对临界资源进行互斥访问的手段。当一个自旋锁已经被其他线程持有,而另一个线程试图去获取自旋锁,这时候就会一直在那里等待(原地自旋等待)。如果递归调用自旋锁,就会导致系统死锁。

  • 信号量

使用方法:

struct semaphore sem;
sema_init(&sem, 1); //将信号初始化为1,大于0,表示空闲

down(&sem);    //对信号量减1,如果大于等于0,则继续执行,否则进入休眠
...
代码
...
up(&sem); //对信号量加1,如果大于0,就唤醒等待队列中的进程。

与自旋锁不同的是,当获取不到信号量时,进程不会原地打转而是进入休眠等待状态。新的Linux内核倾向于直接使用mutex作为互斥手段,信号量用作互斥不再被推荐使用。

  • 互斥体

使用方法:

struct mutex my_mutex;  //定义mutex
mutex_init(&my_mutex);  //初始化mutex

mutex_lock(&my_mutex);    //获取mutex
...
代码
...
mutex_unlock(&my_mutex);  //释放mutex

当进程占用资源事件较长时,用互斥体会比较好。

  • 完成量
DECLARE_COMPLETION(com); //定义并初始化完成量。

wait_for_completion(&com); //线程进入休眠

complete_all(&com);    //唤醒所有等待队列

完成量的机制是实现一个线程发送一个信号通知另一个线程完成某个任务。一个线程调用wait_for_completion后就进入休眠,另一个线程执行完某个任务后就发送通知给进入休眠的线程,然后它就执行wait_for_completion后面的代码。

相关文章
|
8天前
|
缓存 Linux 开发者
Linux内核中的并发控制机制:深入理解与应用####
【10月更文挑战第21天】 本文旨在为读者提供一个全面的指南,探讨Linux操作系统中用于实现多线程和进程间同步的关键技术——并发控制机制。通过剖析互斥锁、自旋锁、读写锁等核心概念及其在实际场景中的应用,本文将帮助开发者更好地理解和运用这些工具来构建高效且稳定的应用程序。 ####
26 5
|
10天前
|
Linux 数据库
Linux内核中的锁机制:保障并发操作的数据一致性####
【10月更文挑战第29天】 在多线程编程中,确保数据一致性和防止竞争条件是至关重要的。本文将深入探讨Linux操作系统中实现的几种关键锁机制,包括自旋锁、互斥锁和读写锁等。通过分析这些锁的设计原理和使用场景,帮助读者理解如何在实际应用中选择合适的锁机制以优化系统性能和稳定性。 ####
27 6
|
3月前
|
NoSQL Unix Linux
Linux 设备驱动程序(一)(上)
Linux 设备驱动程序(一)
162 62
|
3月前
|
Java Linux API
Linux设备驱动开发详解2
Linux设备驱动开发详解
44 6
|
3月前
|
消息中间件 算法 Unix
Linux设备驱动开发详解1
Linux设备驱动开发详解
49 5
|
3月前
|
存储 缓存 Unix
Linux 设备驱动程序(三)(上)
Linux 设备驱动程序(三)
38 3
|
3月前
|
缓存 安全 Linux
Linux 设备驱动程序(一)((下)
Linux 设备驱动程序(一)
33 3
|
3月前
|
安全 数据管理 Linux
Linux 设备驱动程序(一)(中)
Linux 设备驱动程序(一)
28 2
|
3月前
|
Linux
Linux 设备驱动程序(四)
Linux 设备驱动程序(四)
23 1
|
3月前
|
存储 数据采集 缓存
Linux 设备驱动程序(三)(中)
Linux 设备驱动程序(三)
35 1