linux驱动中锁的使用

一、atomic用法

TP代码中每个判断irq_enable的地方全部换成atomic_cmpxchg,对比和设值一起做完,避免在disable已经判断完毕,但是还没给flag赋值时,被中断打断,再次执行disable,中断函数结束后又执行一次disable,每次执行disable都会对desc->depth++,所以连续加两次。之后enable++一次,无法正常使能中断,TP失效。

#include<linux/atomic.h>

static atomic irq_enabled=ATOMIC_INIT(0);

Void gtp_irq_disable(void)

{

if(atomic_cmpxchg(&irq_enabled,1,0))//比较“1”和irq_enabled的值,如果相等,把“0”赋值给原子变量,返回irq_enabled的值

disable_irq(touch_irq);

}

 

Void gtp_irq_enable(void)

{

if(atomic_cmpxchg(&irq_enabled,1,0))//比较“1”和irq_enabled的值,如果相等,把“0”赋值给原子变量,返回irq_enabled的值

enable_irq(touch_irq);

}

 

Void tpd_irq_registration(void)

{

......

atomic_set(&irq_enabled,1);

}

二、spinlock用法

Busy-waiting,锁定临界区小,自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是 否该自旋锁的保持者已经释放了锁。(防止被中断打断)

更保险的方法或许是先(保守的)使用 Mutex,然后如果对性能还有进一步的需求,可以尝试使用spin lock进行调优

 

#include<linux/spinlock.h>

static DEFINE_SPINLOCK(test_lock);

 

int init_test_lock(void)

{

spin_lock_init(&test_lock);

return 0

}//在自旋锁使用之前调用,可以写probe

 

int test(void)

{

......

......

spin_lock(&test_lock);

XXXXX;

XXXXX;

spin_unlock(&test_lock);

.......

.......

}

 

 

三、Mutex的用法

Mutexsleep-waiting,不会一直等待,进程级别的,进程调用时间较长时使用

#include<linux/mutex.h>

static DEFINE_MUTEX(text_lock);//mutex中,如果CONFIG_DEBUG_MUTEXES定义了,会自动init

 

Int test(void)

{

...................

...................

mutex_lock(&test_lock);

XXXXXXXXXXXX;

XXXXXXXXXXXX;

mutex_unlock(&test_lock);

..........

}


代码可直接复制使用,但未经允许,请勿转载

### Linux 驱动开发中互斥 (mutex) 的使用方法及示例 在 Linux 驱动开发中,互斥(mutex)是一种重要的同步机制,用于保护共享资源免受并发访问的影响。以下详细介绍互斥的定义、初始化、加锁、解以及相关 API,并提供一个代码示例以展示其最佳实践。 #### 1. 定义与初始化 互斥通过 `struct mutex` 结构体定义,位于头文件 `<linux/mutex.h>` 中[^1]。可以使用 `mutex_init()` 函数手动初始化互斥,或者通过宏 `DEFINE_MUTEX(name)` 在定义时直接初始化。 ```c #include <linux/mutex.h> // 手动初始化 struct mutex my_mutex; mutex_init(&my_mutex); // 使用宏 DEFINE_MUTEX 初始化 DEFINE_MUTEX(my_mutex); ``` #### 2. 加锁操作 为了确保对共享资源的安全访问,需要在访问前加锁Linux 提供了多种加锁函数,具体选择取决于场景需求: - **不可中断加锁**:`mutex_lock(struct mutex *lock)`,适用于不需要处理信号的场景。 - **可中断加锁**:`mutex_lock_interruptible(struct mutex *lock)`,允许进程在等待时被信号中断。 - **可终止加锁**:`mutex_lock_killable(struct mutex *lock)`,允许进程在等待时被杀死。 ```c // 示例:不可中断加锁 mutex_lock(&my_mutex); // 示例:可中断加锁 if (mutex_lock_interruptible(&my_mutex)) { // 如果被信号中断,则返回错误 return -ERESTARTSYS; } ``` #### 3. 解操作 当完成对共享资源的操作后,必须释放以允许其他进程访问资源。使用 `mutex_unlock(struct mutex *lock)` 函数解。 ```c mutex_unlock(&my_mutex); ``` #### 4. 尝试加锁 如果不想让当前线程阻塞等待,可以使用 `mutex_trylock(struct mutex *lock)` 尝试获取。成功时返回 1,失败时返回 0 并不会阻塞。 ```c if (mutex_trylock(&my_mutex)) { // 成功获取,执行操作 mutex_unlock(&my_mutex); // 操作完成后解 } else { // 已被占用,执行其他逻辑 } ``` #### 5. 判断状态 可以通过 `mutex_is_locked(struct mutex *lock)` 检查是否已被占用。这通常用于调试或特定场景下的逻辑判断。 ```c if (mutex_is_locked(&my_mutex)) { // 已被占用 } ``` #### 6. 示例代码 以下是一个完整的代码示例,展示了如何在 Linux 驱动程序中使用互斥保护共享资源。 ```c #include <linux/module.h> #include <linux/kernel.h> #include <linux/mutex.h> static struct mutex my_mutex; // 定义互斥 static int shared_resource = 0; // 共享资源 static int __init my_module_init(void) { mutex_init(&my_mutex); // 初始化互斥 if (mutex_lock_interruptible(&my_mutex)) { printk(KERN_INFO "Lock acquisition interrupted.\n"); return -ERESTARTSYS; } // 模拟对共享资源的操作 shared_resource++; printk(KERN_INFO "Shared resource value: %d\n", shared_resource); mutex_unlock(&my_mutex); // 解 return 0; } static void __exit my_module_exit(void) { if (mutex_trylock(&my_mutex)) { // 再次操作共享资源 shared_resource--; printk(KERN_INFO "Shared resource value on exit: %d\n", shared_resource); mutex_unlock(&my_mutex); } else { printk(KERN_INFO "Mutex is already locked, cannot access shared resource.\n"); } } module_init(my_module_init); module_exit(my_module_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Your Name"); MODULE_DESCRIPTION("Example of using mutex in Linux driver"); ``` #### 7. 注意事项 - 确保每次加锁后都有对应的解操作,避免死。 - 不要在中断上下文中使用互斥,因为它们可能会导致睡眠[^1]。 - 使用 `DEFINE_MUTEX` 宏时需注意变量的作用域和生命周期。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值