【问题标题】:Where to use binary semaphore when mutex are available?互斥量可用时在哪里使用二进制信号量?
【发布时间】:2012-07-16 16:50:17
【问题描述】:

在阅读二进制信号量和互斥锁时,我发现了以下区别:

两者都可以有值 0 和 1,但互斥锁可以被相同的解锁 获得互斥锁的线程。获取的线程 互斥锁可以在更高优先级的情况下进行优先级反转 进程想要获取相同的互斥体,但事实并非如此 带有二进制信号量。

那么我应该在哪里使用二进制信号量?谁能举个例子?

编辑:我想我已经弄清楚了两者的工作原理。基本上二进制信号量提供同步,而互斥量提供锁定机制。我阅读了 Galvin OS 书中的一些示例以使其更加清晰。

【问题讨论】:

    标签: c operating-system mutex semaphore


    【解决方案1】:

    我发现二进制信号量非常有用的一种典型情况是线程初始化,其中线程将从父线程拥有的结构中读取。父线程需要等待新线程从结构中读取共享数据,然后才能让结构的生命周期结束(例如,通过离开其范围)。使用二进制信号量,您所要做的就是将信号量值初始化为零并让子级在父级等待时发布它。如果没有信号量,您将需要一个互斥体和条件变量以及更丑陋的程序逻辑来使用它们。

    【讨论】:

      【解决方案2】:

      在几乎所有情况下,我都使用二进制信号量来向其他线程发出信号而不加锁。

      同步请求的简单使用示例:

      线程 1

      Semaphore sem;
      request_to_thread2(&sem); // Function sending request to thread2 in any fashion
      sem.wait();               // Waiting request complete
      

      线程 2

      Semaphore *sem;
      process_request(sem);     // Process request from thread 1
      sem->post();              // Signal thread 1 that request is completed
      

      注意:在线程 2 处理中发布信号量之前,您可以安全地设置线程 1 数据,而无需任何额外的同步。

      【讨论】:

        【解决方案3】:

        使用计数信号量而不是二进制互斥锁的典型示例是当您的可用资源数量有限时,a) 可互换且 b) 不止一个。

        例如,如果您希望最多允许 10 个读者同时访问数据库,您可以使用初始化为 10 的计数信号量来限制对资源的访问。每个读取器必须在访问资源之前获取信号量,从而减少可用计数。一旦计数达到 0(即 10 个读者已获得访问权限并仍在使用数据库),所有其他读者都将被锁定。读取器完成后,他们会将信号量计数增加 1 以表明他们不再使用该资源,并且其他读取器现在可能会获得信号量锁并获得访问权限。

        然而,计数信号量,就像所有其他同步原语一样,有很多用例,只是跳出框框思考问题。您可能会发现,您习惯于使用互斥锁和附加逻辑解决的许多问题都可以使用信号量更轻松、更直接地实现。互斥量是信号量的一个子集,也就是说,你可以用互斥量做的任何事情都可以用一个信号量来完成(只需将计数设置为 1),但是有些事情可以单独用一个信号量来完成不能只使用互斥锁。

        归根结底,任何一个同步原语通常都足以做任何事情(将其视为线程同步的“图灵完备”,以贬低这个词)。然而,每一个都是为不同的应用程序量身定做的,虽然你可以通过一些定制和额外的粘合来强迫一个人做你的竞标,但不同的同步原语可能更适合这项工作。

        【讨论】:

        • OP 询问的是二进制信号量与(始终二进制)互斥体,而不是计算信号量与互斥体。
        猜你喜欢
        • 2022-11-01
        • 1970-01-01
        • 2021-08-14
        • 1970-01-01
        • 2021-11-11
        • 2015-05-24
        • 2010-09-08
        • 2022-11-05
        • 2016-08-30
        相关资源
        最近更新 更多