【问题标题】:How does mutex or semaphore wake up processes?互斥量或信号量如何唤醒进程?
【发布时间】:2011-06-24 14:52:26
【问题描述】:

我读到互斥锁和信号量维护一个等待进程列表,并在当前线程完成临界区时唤醒它们。互斥锁和信号量如何做到这一点?它们不会干扰进程调度器的决策吗?

【问题讨论】:

    标签: multithreading synchronization mutex semaphore


    【解决方案1】:

    等待和唤醒通常与调度程序合作完成。强制唤醒特定等待线程的互斥锁实现通常被认为是一个糟糕的实现。

    相反,互斥锁或信号量将通知调度程序线程正在等待,从而将其从“准备运行”列表中删除。然后,当互斥锁被解锁或信号量发出信号时,实现将要么

    1. 要求调度程序根据调度程序的判断唤醒其中一个等待线程,或者

    2. 通知调度程序所有等待线程都准备好运行,然后对等待线程进行逻辑处理,以便除第一个被调度程序唤醒的线程之外的所有线程都再次进入睡眠状态。

    前者是首选的实现选择,但并不总是可用。第二种通常被称为“雷鸣群”方法:如果有 1000 个线程在等待,那么所有 1000 个都被唤醒(一大群雷鸣般的线程),只有 999 个重新进入睡眠状态。这是对 CPU 资源的浪费,实现会尽可能避免。

    【讨论】:

    • 内容丰富!但是我还是有一些疑问:为什么调度器不能只取队列中的第一个来运行,而不唤醒队列中的所有线程?目前linux上的posix线程库实现了这两者中的哪一个?谢谢!
    • 这是上面的选项 1:由调度程序自行决定唤醒一个。
    • @zach “为什么调度程序不能只获取队列中的第一个” - 因为这就是它被称为 shedular 的原因,它不能只唤醒队列中的第一个或第二个。它具有每个线程的优先级,并按优先级唤醒线程。有关信息,您可以查看线程调度,这本身就是完全不同的主题。
    【解决方案2】:

    这在很大程度上取决于实施。说到这些,我们通常指的是线程,它可能有操作系统支持,也可能完全用语言实现,因此甚至不与O/S交互来支持线程。

    不过,它们也可以引用进程,但这些实现通常需要复杂的消息传递模式,此外还需要一些 O/S 对进程管理的支持。

    【讨论】:

      【解决方案3】:

      是的,简单的解释是,任何等待进程(无论是信号量还是 I/O)都会从调度程序的运行队列中取出,直到满足其等待条件。

      【讨论】:

        猜你喜欢
        • 2017-08-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-01
        • 2011-04-20
        • 2021-11-11
        • 2014-03-01
        • 1970-01-01
        相关资源
        最近更新 更多