电电侠 (神秘兮兮地)科,你知道吗?程序世界里有个神奇的小开关,叫做“二值信号量”。
(若有所思)二值信号量?我略有了解。
科科君
信号量本质上是一个程序数据项,用于决定任务继续运行还是挂起。信号量类型有两种,二值信号量和通用型/计数信号量。两者的工作原理相同,信号量原语最初由 Edsger Dijkstra在1965年提出。
电电侠 科科大大分析下? 首先分析二值信号量。
科科君
本质上,二值信号量是一个任务流控制机制,可以将其比作铁路信号
火车将根据信号位置情况,决定通过该点还是必须停止。如果火车停下来,它们会保持在该位置直到信号变为“允许通行”。以类似的方式,信号量可以允许任务继续执行其代码或挂起。一旦任务挂起,它将保持在此状态,直到某些程序操作使该任务重新就绪。
电电侠 在铁路系统中,信号可算是安全机制。 是的,这种安全机制用于控制列车运行,从而防止碰撞、损坏或人身事故。
科科君
实际的铁路网络中还有很多信号,可根据需要使用这些信号。同样,多任务设计中也可能使用许多信号量,每个信号量都相当于一个特定的信号。
在并发软件中,信号量用于两个截然不同的目的。此处描述的功能是作为互斥(消除争用)机制,每个共享资源分配一个信号量。信号量也用于同步,实现任务交互。
电电侠 有没有类似的信号量的概念图。 下图为用于访问控制时信号量的概念。
科科君
二值信号量用于互斥—概念
该类比是停车场入口控制,信号量相当于控制机制。这里的共享资源是一个单独的停车位,用于上下客。需要确保有且只有一辆车可以进入停车位。因此,用户在尝试停车之前,必须首先检查停车位是否空闲。为此使用了一个访问控制接口,其包括:
(1)“请求”按钮。用户按下此按钮以向停车场服务员发出需要进入停车场的信号。
(2)“结束”按钮。用户在退出时,按此按钮通知服务员,停车位再次空闲。
(3)扬声器。停车场服务员用它来回答用户的请求。
在此类比中,二进制信号量等价于访问控制机制的软件实现,这里用户指的是任务。
电电侠 我知道。假设最初停车场资源处于空闲状态。第一个操作是向停车场服务员提供此状态信息 (假设从控制室看不到停车位)。其对应的软件操作将初始化该信号量。同样,服务员功能由操作系统软件提供。 是的。当然,还有以下情况。
科科君
当用户需要使用停车资源时,它靠近屏障并按下请求按钮,在信号量术语中,该行为被定义为信号等待(wait)操作。由于资源处于空闲状态,故服务员抬起屏障并回答可以通过, 用户随即进入保护区域,然后屏障关闭。
某个时刻用户离开并腾出停车位,在退出时按下结束按钮,发出信号给访问控制机制, 该行为被定义为信号发布(signal)操作。操作结果将更新服务员看到的状态信息,显示停车场再次空闲。
电电侠 那当另一辆车到达时资源正在使用时,请求服务的用户该怎么办? 该用户会被放置到等待队列(对应于任务挂起)。
科科君
当前资源占用者,一旦完成工作,在离开停车位时将生成一个信 号,控制机制收到该信号,标记资源空闲。但随后的事件遵循了不同的模式,没有更新服务员的状态信息。取而代之的是抬起屏障并发送“通过”消息给等待的用户(相当于一个任务唤醒另一个任务),授权用户进入保护区域;后续的事件处理过程与前面一致。
电电侠
当任务1已经处于等待队列中时,一个更高优先级的任务(比如任务3)到达,系统如何处理?
实际上,结果取决于使用的排队策略。通常队列使用两种排队策略,先进先出(FIFO)策略和优先级抢占策略。
科科君
使用先进先出策略排队时,任务3排在任务1的后面。因此条件允许(即空间可用)时, 任务1可以立即执行。此方式虽然安全,但导致较低优先级的任务延迟了较高优先级任务 的执行,可能导致严重的系统问题。
如果使用优先级抢占策略,任务3优先并排在队列前面,因此它将第一个就绪。但该方式延迟了任务1的执行,也会导致潜在的性能问题(任务饥饿)。由设计者来决定使用哪种方法以及在何处使用它,但无论哪种情况,任务行为建模都如下图所示。
任务行为建模
如前所述,为每个受控的资源创建一个信号量,在编程术语中,信号量被看作一个命名的数据项。下面来看一个简单的应用程序。
科科君 简单应用程序
首先创建一个信号量,命名为CoefficientsSemaphore,可执行的操作包括等待信号量 Wait(CoefficientsSemaphore)和发 布信号量Signal(CoefficientsSemaphore)。二进制信号量只有两个值,“0”或“1”。“0”表示资源正在使用中,“1”表示资源当前空 闲。在其初始形式中,信号量操作见代码清单1和代码清单2。
代码清单1
代码清单2
在程序中,将在需要的位置使用上述代码段,如代码清单3所示。
代码清单3
电电侠 那定义wait和signal操作为什么类型? wait和signal操作被定义为“原语”类型,即每个操作都是不可分割的。
科科君
换言之,一旦 wait或signal处理开始,其对应的机器指令序列不能被中断。这是必不可少的,否则会遇到和单一标志互斥机制相同的问题。提供原子性操作不是一件轻松的任务,它可能会带来实现上的困难,但系统必须克服困难实现信号量。此外,这些原语操作必须由操作系统而非程序员保护。
二进制信号量可以实现为单字节,甚至是字节中的一位,使用一条“位设置和测试”指令 39 实现。但是,如果测试和检查涉及多条处理器指令时,该方法行不通。在这种情况下,通过在信号量操作执行之前禁用系统中断,确保操作的原子性。资源操作完成后,重新启用中断。
(敲黑板)
科科君
此技术通常不适用于多处理器系统,多处理器系统需要一种硬件锁定机制。wait和signal也称为 P操作和 V 操作,源自荷兰语词汇。关于它们实际指代的词存在一些分歧,最流行的是prolaag和verhogen。
原语是为完成特定的功能而编写的一段程序,它在执行时不可分割、不可中断。
审核编辑:黄飞
评论
查看更多