第十一章 信号(一)- 概念

2022-06-27  本文已影响0人  Cache技术分享

第十一章 信号(一) - 概念

背景

维基百科对信号量有这样的定义:“在计算机科学中,特别是在操作系统中,信号量是一种变量或抽象数据类型,用于控制多个进程在并行编程或多用户环境中对公共资源的访问。”信号量不同于互斥体(或锁)。互斥锁最常用于管理竞争进程对单个资源的访问。当一个资源有多个相同的副本并且这些副本中的每一个都可以由单独的进程同时使用时,就会使用信号量。

考虑一个办公用品商店。它可能有几台复印机供其客户使用,但每台复印机一次只能由一个客户使用。为了控制这一点,有一组键可以启用机器并记录使用情况。当客户想要复印文件时,他们向职员索取钥匙,使用机器,然后归还钥匙,并支付使用费。如果所有机器都在使用,客户必须等到钥匙归还。保存键的位置用作信号量。

该示例可以进一步推广到包括不同类型的复印机,也许可以通过它们可以制作的副本的大小来区分。在这种情况下,将有多个信号量,如果复制者在复制的大小上有任何重叠,那么希望复制共同大小的客户将有两个资源可供提取。

介绍

信号量是共享对象,用于在进程之间提供快速、高效的通信。每个信号量都是类 %SYSTEM.Semaphore 的一个实例。信号量可以建模为一个共享变量,它包含一个 64 位非负整数。信号量上的操作在共享它的所有进程中以同步的方式更改变量的值。按照惯例,值的变化会在共享信号量的进程之间传递信息。

尽管信号量和锁似乎有很多共同点,但使用信号量还是有一些优势的。其中最主要的事实是,当信号量被授予时,信号量会导致发送通知。因此使用信号量的进程不需要花费处理器周期或复杂的应用程序逻辑轮询锁以检查它是否已被释放。此外,信号量在 ECP 连接上透明地工作,并且比在相同情况下检查锁所需的交换效率更高。

信号概述

信号名称

信号量由它们的名称标识,这些名称在创建信号量时作为 ObjectScript 字符串提供。为信号量指定的名称应符合局部和全局变量的规则。信号量名称只是为了将其与所有其他现有信号量区分开来。有效名称字符串的示例有:SlotsOpen, J(3), ^pendingRequest(""j"")

通常,信号量存储在创建该信号量的实例上,并且对该实例上的所有进程可见。但是,当信号量名称看起来像全局变量的名称时,信号量存储在映射全局变量(包括下标)的系统上。这允许这样的信号量对在ECP系统的实例上运行的所有进程可见。

注意:信号量的名称是一个字符串,但在运行时可以由诸如"^" _ BaseName _ "(" _ (1 + 2) _ ")"这样的表达式构造。如果BaseName包含字符串“prters”,则信号量名称为^prters(3)

信号量值

信号量值存储为63位无符号整数,因此信号量值始终大于或等于零。

最大的63位无符号整数是9,223,372,036,854,775,807((2**63)-1)。信号量不能超过此值递增,也不能递减到零以下。

信号量实例和变量

信号量是派生自 %SYSTEM.Semaphore 的类的实例。一旦信号量被创建和初始化,它的 OREF 通常存储在一个 Objectscript 变量中,因此它可以用于其他操作,作为参数传递,并最终被删除。尽管包含对信号量的引用的变量的名称不必与信号量的名称相对应,但良好的编程习惯表明存在某种关系。

像所有对非持久数据的对象引用一样,当最后一个信号量引用被回收时,底层信号量也被删除。

信号量操作

基础

信号量操作可以分为两大类:直接操作信号量的操作和等待其他进程操作信号量的操作。第一组包括:

管理多个信号量

第二组操作涉及将信号量列表作为一个组进行管理,并等待每个 on 待处理的操作完成:

等候队列

每个使用 WaitMany 协调多个信号量的进程将信号量减量操作请求保存在一个内部列表中。对列表的操作处理如下:

回调

信号量的实例继承一个抽象方法WaitComplete,用户需要实现该方法。在处理等待列表上满足的请求时,WaitMany对等待列表中的每个信号量调用WaitComplete方法,并将信号量递减的数量作为参数传递。当WaitComplete返回时,WaitMany将从等待列表中删除该请求。

其他考虑事项

同一等待列表上有多个递减请求

在同一等待列表中多次请求递减同一信号量并不是错误的。添加的请求处理方式如下:

在调用WaitMany之前,不会通过回调报告递减量,因此对同一信号量的多个请求看起来就像是发出了一个组合请求。这会导致以下情况:

  1. 信号量A设置为0
  2. A 的减量请求 4
  3. A 的减量请求为 1;新的减量 = 5
  4. 信号量 A 设置为 4
  5. 请求满足; 4 授予。
  6. call waitmany ;等待完成A报告。
  1. 信号量A设置为1
  2. A的减量请求,共3个。
  3. 请求满足; 1 授予。
  4. A 的减量请求 4
  5. call WaitMany; WaitCompleted for A 报告 1。
  1. 信号量 A 设置为 1
  2. A 的减量请求为 3
  3. 请求满足; 1 授予。
  4. A 的减量请求 4
  5. 信号量 A 设置为 5
  6. 请求满足; 4 授予。
  7. 调用WaitManyWaitCompleted for A 报告 5;信号量 A= 1

信号量删除

信号量没有所有者,并且它们不像对象实例那样被引用计数。任何可以打开信号量的进程都可以将其删除。

当一个信号量被删除时,

  1. 如果任何等待列表中存在该信号量的挂起递减,则调用 WaitCompleted 回调,递减值为零。
  2. 它将从映射的系统(本地或远程)中删除。
  3. 任何其他进程进一步尝试访问它都会失败,并出现 <INVALID SEMAPHORE>错误。

工作终止和等待列表

进程终止时,它的等待列表被释放。保留在等待列表中但尚未由 WaitMany 处理的任何满足的递减请求都将被清除。它们各自的递减量不会添加回它们递减的信号量。等待列表中的任何未满足的请求都将被简单地删除。

信号量和 ECP

对于 ECP 系统上的信号量,信号量上的操作按照请求到达持有信号量的系统的顺序进行排序。每个操作都保证在下一个操作开始之前完成。远程信号量保证以下条件:

因为信号量不是持久的,所以在服务中断的情况下,ECP 系统上跨服务器的未决信号量操作是不可恢复的。由于服务器或网络故障导致 ECP 中断后,应用服务器上的信号量将被删除,数据服务器上的待处理请求也将被删除。应用程序有责任检测这种情况并在正确状态下重新创建所需的信号量。

上一篇下一篇

猜你喜欢

热点阅读