class Semaphore { }

使用信号量保护共享代码、数据或设备访问。一个示例是打印机管理器管理一组打印机,而无需在所有打印机都处于占用状态时存储打印作业。下一个作业将被阻塞,直到有打印机可用。

class print-manager {
  has Array $!printers;
  has Semaphore $!print-control;
 
  method BUILDInt:D :$nbr-printers ) {
    for ^$nbr-printers -> $pc {
      $!printers[$pc= { :name{"printer-$pc"} };
    }
 
    $!print-control .= new($nbr-printers);
  }
 
  method find-available-printer-and-print-it($job{ say "Is printed!"}
 
  method print$print-job ) {
    $!print-control.acquire;
 
    self.find-available-printer-and-print-it($print-job);
 
    $!print-control.release;
  }
}

另一个示例是对更新敏感数据的代码的保护。在这种情况下,信号量通常初始化为 1。

在程序的每个退出点都必须有一个 release!虽然这很明显,但很容易陷入陷阱,例如抛出由某些事件引起的异常。当程序终止时,没有问题。当异常被捕获时,程序最终可能会返回到 acquire 方法,并且会无限期地挂起。

方法§

方法 new§

method newint $permits )

使用允许的访问次数初始化信号量。例如,当设置为 2 时,程序线程可以传递 acquire 方法两次,直到它在第三次调用 acquire 时被阻塞。

方法 acquire§

method acquire()

获取访问权限。当其他线程在之前调用了该方法并且许可证数量已用尽时,该进程将阻塞,直到之前传递的线程释放信号量。

方法 try_acquire§

method try_acquire(--> Bool)

与 acquire 相同,但不会阻塞。相反,如果允许访问,则返回 True,否则返回 False

方法 release§

method release()

释放信号量,增加许可证数量。之后,任何被阻塞的线程都将获得访问权限。

类型图§

Semaphore 的类型关系
raku-type-graph Semaphore Semaphore Any Any Semaphore->Any Mu Mu Any->Mu

展开上方的图表