【问题标题】:Use a Monitor like a Semaphore?使用像信号量这样的监视器?
【发布时间】:2014-10-15 07:56:32
【问题描述】:

当使用监视器来解决大多数并发问题时,您可以将关键部分放在监视器方法中,然后调用该方法。但是,有一些多路复用问题,其中多达 n 个线程可以同时运行它们的关键部分。所以我们可以说了解如何使用如下监视器很有用:

monitor.enter();
runCriticalSection();
monitor.exit();

我们可以在监视器中使用什么来执行此操作?

附带问题:是否有解决此问题的标准资源?我读到的大部分内容只涉及将关键部分放在监视器内。对于信号量,有“信号量小书”。

【问题讨论】:

  • 有一些多路复用问题,其中多达 n 个线程可以同时运行它们的关键部分 - 不清楚。根据定义,临界区是一段代码,一次只能由一个线程执行。
  • @MaximYegorushkin 啊,我明白了。我扩展了“临界区”的使用,以指代最多只能执行 n 次的代码。你对我所说的临界区有什么别的称呼吗?

标签: multithreading concurrency synchronization


【解决方案1】:

据我了解您的问题,任何解决方案都必须满足这一点:

  • 当少于 n 个线程处于临界区时,调用 monitor.enter() 的线程不应阻塞 — 即唯一阻止它前进的应该是调度程序的突发奇想。
  • 在任何时间点,最多有 n 个线程处于临界区;暗示
  • 当线程 n+1 调用monitor.enter() 时,它必须阻塞直到线程调用monitor.exit()

据我所知,您的要求是这样的:

  • “监视器”是一个初始值为n 的信号量。
  • monitor.enter()semaphore.prolaag()(又名 Pdecrementwait
  • monitor.exit()semaphore.verhoog()(又名 Vincrementsignal

这就是从监视器实现的信号量:

monitor Semaphore(n):
    int capacity = n
    method enter:
        while capacity == 0: wait()
        capacity -= 1
    method exit:
        capacity += 1
        signal()

像这样使用它:

shared state:
    monitor = Semaphore(n)

each thread:
    monitor.enter()
    runCriticalSection()
    monitor.exit()

另一条路

我猜你可能想要某种语法包装器,我们称之为 Multimonitor,所以你可以这样写:

Multimonitor(n):
    method critical_section_a:
        <statements>
    method critical_section_b:
        <statements>

并且您的运行时环境将确保在任何监视器方法中最多有 n 个线程处于活动状态(在您的情况下,您只需要一种方法)。我知道在任何编程语言或运行时环境中都没有这样的功能。

也许在python中你可以创建一个包含所有簿记变量的Multimonitor类,然后从它继承子类并在所有方法上放置装饰器;涉及元类的解决方案可能能够为用户进行装饰。

第三个选项

如果您使用信号量实现监视器,您通常会使用信号量作为监视器入口和恢复点周围的互斥锁。我认为您可以使用大于 1 的值初始化这样的信号量,从而生成这样的 Multimonitor,并在条件变量上加上 wait()signal()。但是:它会比您在陈述的问题中需要做的更多,如果您使用信号量,为什么不以基本和直接的方式使用它们?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-12
    • 2018-04-05
    • 1970-01-01
    相关资源
    最近更新 更多