【问题标题】:Linux kernel mutexesLinux 内核互斥体
【发布时间】:2011-06-13 01:44:13
【问题描述】:

我正在阅读“Linux 设备驱动程序第 3 版”,关于并发和竞争条件的章节。有一个我不完全理解的例子;他们谈论的是内核编程中的一种常见模式,当需要在当前线程之外启动活动(例如,新的内核线程或用户进程、对现有进程的请求或基于硬件的操作)时,等待该活动完全的。不是很有效的解决方案的例子是:

struct semaphore sem;
init_MUTEX_LOCKED(&sem);
start_external_task(&sem);
down(&sem);

然后他们建议外部任务在其工作完成时调用(&sem)。

我不明白为什么我们不能这样做:

struct semaphore sem;
down(&sem);
start_external_task(&sem);

为什么要在锁定状态下创建互斥锁,然后在任务启动后获取互斥锁?

期待您的回音!谢谢。

【问题讨论】:

    标签: c linux multithreading kernel


    【解决方案1】:

    当您调用 down() 时,您的线程将阻塞,直到另一个线程发出信号量。由于其他线程尚未启动,该线程将无限期阻塞。这就是为什么你需要先启动线程,然后调用down()来阻塞,直到线程结束。

    如果线程在你调用 down() 之前完成,那没关系,因为信号量会发出信号,而 down() 会简单地清除信号并返回。

    【讨论】:

    • +1,但我认为使用术语semaphore 而不是mutex 会更好。 SEMAPHORE:可以由任何线程向上/向下。 MUTEX:拥有所有权,只有锁拥有者线程可以up mutex。在这种情况下,我们需要使用信号量,因为它的目的是线程之间的通信......
    • @Vojita:我同意。我使用术语互斥锁是因为问题将信号量称为互斥锁。
    【解决方案2】:

    在第一个示例中,down(&sem) 将等待 external_task 调用(&sem) 并有效地暂停主线程直到任务完成。 在您的代码中,down() 将永远锁定主线程,因为还没有任务可以调用 up()

    【讨论】:

      【解决方案3】:

      电话:

      init_MUTEX_LOCKED(&sem);
      

      在“互斥模式”中创建一个新的信号量,初始化为 0。这意味着对 down() 的调用将被阻塞。对应的调用:

      init_MUTEX(&sem);
      

      将创建一个初始化为 1 的信号量。

      在第一个示例中,您将信号量初始化为 0,创建 external_task 并调用 down() 阻塞,直到您的任务调用 up()

      在第二个示例中,您没有初始化信号量,调用down() 阻塞执行,并且没有运行可以调用up() 来解除阻塞的external_task。因此,创建 external_task 的调用永远不会到达。

      顺便说一句,使用 init_MUTEX_LOCKED 初始化信号量的过程已在内核版本 2.6.37 中删除。

      【讨论】:

        猜你喜欢
        • 2014-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-08
        相关资源
        最近更新 更多