Linux内核互斥锁

/linux/include/linux/mutex.h

  

<!-- @page { size: 21.59cm 27.94cm; margin: 2cm } P { margin-bottom: 0.21cm } -->

二、作用及访问规则:

互斥锁主要用于实现内核中的互斥访问功能。内核互斥锁是在原子 API 之上实现的,但这对于内核用户是不可见的。对它的访问必须遵循一些规则:同一时间只能有一个任务持有互斥锁,而且只有这个任务可以对互斥锁进行解锁。互斥锁不能进行递归锁定或解锁。一个互斥锁对象必须通过其API初始化,而不能使用memset或复制初始化。一个任务在持有互斥锁的时候是不能结束的。互斥锁所使用的内存区域是不能被释放的。使用中的互斥锁是不能被重新初始化的。并且互斥锁不能用于中断上下文。但是互斥锁比当前的内核信号量选项更快,并且更加紧凑,因此如果它们满足您的需求,那么它们将是您明智的选择。

三、各字段详解:

1、atomic_t count;

指示互斥锁的状态:

1 没有上锁,可以获得

0 被锁定,不能获得

负数 被锁定,且可能在该锁上有等待进程

初始化为没有上锁。

2、spinlock_t wait_lock;

等待获取互斥锁中使用的自旋锁。在获取互斥锁的过程中,操作会在自旋锁的保护中进行。初始化为为锁定。

3、struct list_head wait_list;

等待互斥锁的进程队列。

四、操作:

1、定义并初始化:

struct mutex mutex;

mutex_init(&mutex);

  

<!-- @page { size: 21.59cm 27.94cm; margin: 2cm } P { margin-bottom: 0.21cm } -->

直接定于互斥锁mutex并初始化为未锁定,己count为1,wait_lock为未上锁,等待队列wait_list为空。

2、获取互斥锁:

(1)具体参见linux/kernel/mutex.c

<!-- @page { size: 21.59cm 27.94cm; margin: 2cm } P { margin-bottom: 0.21cm } -->

void inline fastcall __sched mutex_lock(struct mutex *lock);

<!-- @page { size: 21.59cm 27.94cm; margin: 2cm } P { margin-bottom: 0.21cm } -->

获取互斥锁。实际上是先给count做自减操作,然后使用本身的自旋锁进入临界区操作。首先取得count的值,在将count置为-1,判断如果原来count的置为1,也即互斥锁可以获得,则直接获取,跳出。否则进入循环反复测试互斥锁的状态。在循环中,也是先取得互斥锁原来的状态,在将其之为-1,判断如果可以获取(等于1),则退出循环,否则设置当前进程的状态为不可中断状态,解锁自身的自旋锁,进入睡眠状态,待被在调度唤醒时,再获得自身的自旋锁,进入新一次的查询其自身状态(该互斥锁的状态)的循环。

(2)具体参见linux/kernel/mutex.c

int fastcall __sched mutex_lock_interruptible(struct mutex *lock);

和mutex_lock()一样,也是获取互斥锁。在获得了互斥锁或进入睡眠直到获得互斥锁之后会返回0。如果在等待获取锁的时候进入睡眠状态收到一个信号(被信号打断睡眠),则返回_EINIR。

(3)具体参见linux/kernel/mutex.c

int fastcall __sched mutex_trylock(struct mutex *lock);

试图获取互斥锁,如果成功获取则返回1,否则返回0,不等待。

3、释放互斥锁:

具体参见linux/kernel/mutex.c

void fastcall mutex_unlock(struct mutex *lock);

<!-- @page { size: 21.59cm 27.94cm; margin: 2cm } P { margin-bottom: 0.21cm } -->

释放被当前进程获取的互斥锁。该函数不能用在中断上下文中,而且不允许去释放一个没有上锁的互斥锁。

<!-- @page { size: 21.59cm 27.94cm; margin: 2cm } P { margin-bottom: 0.21cm } -->

五、使用形式:

struct mutex mutex;

mutex_init(&mutex); /*定义*/

...

mutex_lock(&mutex); /*获取互斥锁*/

... /*临界资源*/

mutex_unlock(&mutex); /*释放互斥锁*/


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wxdvc/archive/2009/03/04/3956233.aspx

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 调试内核互斥问题的方法有很多种,下面是一些常见的方法: 1. 在内核代码中加入 printk 语句来跟踪互斥的使用情况。 2. 使用内核调试工具,如 kgdb、kdb 和 kprobes。这些工具可以让你在内核中设置断点,并跟踪代码执行。 3. 使用内核 trace 工具,如 ftrace 和 perf。这些工具可以记录内核函数的调用情况,并帮助你分析互斥的使用情况。 4. 使用内核模拟器,如 QEMU。这些工具可以在用户空间模拟内核的执行,并帮助你调试内核代码。 5. 在内核代码中加入 lockdep 的断言。lockdep 是一个内核调试工具,可以帮助你检测互斥使用的问题。 6. 使用第三方工具,如 LKDTM (Linux Kernel Dynamic Testing Module)。LKDTM 可以在内核中注入故障来帮助你测试互斥的正确性。 需要注意的是,调试内核代码需要具备一定的内核知识,并且需要使用特殊的工具和方法。如果你不熟悉内核开发,建议先读一些内核开发的书籍或者教程,并练习使用这些工具。 ### 回答2: 调试内核互斥问题可以采取以下步骤: 1. 分析问题:首先需要分析和了解问题的具体表现和特征。确定互斥问题的具体场景和出现频率,以及可能的原因。 2. 确认问题源:使用调试工具,例如调试器或代码的日志记录功能,定位出引起互斥问题的具体代码区块。检查代码中是否存在对同一个多次上或释放操作不匹配的情况。 3. 查看互斥的使用:检查代码中对互斥的使用情况,确保在必要时进行正确的上和解操作。尤其需要确保在任何可能的代码路径中都正确使用了互斥。 4. 检查并发访问:查看代码中是否存在多个线程同时对临界区的访问,以及是否在操作共享资源时正确使用了互斥。确保互斥可以正确同步不同线程对共享资源的访问。 5. 分析死:如果程序发生死或出现无法执行的情况,需要分析死的原因。检查是否存在循环等待的情况,以及是否在正确的时机释放互斥。 6. 运行时分析工具:使用运行时分析工具(例如Valgrind、GDB等)来跟踪和分析互斥问题。这些工具可以提供更详细的运行时信息,并帮助定位代码中的潜在问题。 7. 测试和验证:对修复后的互斥问题进行测试和验证,确保问题得到解决。可以模拟并发访问和并行执行的情况,以验证互斥的正确性和可靠性。 综上所述,调试内核互斥问题需要分析问题、确认问题源、查看互斥的使用、检查并发访问、分析死、使用运行时分析工具以及进行测试和验证。通过逐步排查和修复问题,可以提高内核互斥的稳定性和可靠性。 ### 回答3: 要调试内核互斥问题,通常可以按照以下步骤进行: 1.观察现象:首先,根据用户报告或日志,观察系统运行时出现的问题现象,例如死、竞争条件、无法访问共享资源等。 2.追踪代码:通过调试器或日志,追踪与互斥相关的代码,找出可能导致问题的代码段。关键是找到哪些地方使用了互斥,以及它们的顺序和调用关系。 3.检查的使用方式:仔细检查代码,确保互斥的使用方式正确。比如,在访问共享资源之前是否正确加,在完成后是否正确解,并确保解和加的顺序一致。 4.分析竞争条件:对于可能出现竞争条件的地方,需要进一步分析代码逻辑,确定是否会导致资源冲突。可以使用工具或技术,如静态代码分析、代码审查等来辅助。 5.验证问题解决:一旦确定了问题所在,根据分析结果修改代码。然后经过验证,观察问题是否已经解决。可以通过重现问题、运行测试用例或模拟环境等进行验证。 6.防止再次出现:调试解决了当下的问题,但为了防止类似问题再次出现,可以考虑增加一些防护措施,如添加更多的、调整的粒度、优化并发访问策略等。 调试内核互斥问题需要深入理解操作系统内核相关的知识和对并发编程的了解。此外,还需要熟悉调试工具、代码审查和分析技术,以便更好地定位和解决问题。不同的问题可能需要不同的解决方法,需要具体问题具体分析。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值