什么是 Semaphore? 计数、二进制类型示例

⚡ 智能摘要

Semaphore 在操作系统中,`wait` 是一个在线程之间共享的非负整数变量,它通过等待和信号这两个原子操作来协调对共享资源的访问,从而防止进程同步期间出现竞争条件。

  • 🔢 定义: 信号量是一个非负整数变量,用于指示共享资源是否可供竞争线程使用。
  • ⚙️ 二 Opera位置: 等待 (P) 操作请求资源并递减计数,而信号 (V) 操作释放资源并递增计数。
  • 🔁 计数类型: 计数信号量允许一定数量的线程同时使用相同的资源。
  • 🔒 二进制类型: 二元信号量只能取值 0 和 1,因此它的行为就像一个简单的互斥锁。
  • ⚠️ 权衡: Semaphores 具有与机器无关且灵活的特点,但如果使用不当,则存在优先级反转和死锁的风险。
  • 🤖 人工智能辅助: 机器学习和人工智能编码助手可以对并发进行建模,并生成正确的等待和信号序列。

Semaphore in Opera系统

什么是 Semaphore?

Semaphore 只是一个非负且在线程之间共享的变量。信号量是一种信号机制,等待信号量的线程可以由另一个线程发出信号。它使用两个原子操作,1) 等待,和 2) Signal 用于进程同步。

信号量可以允许或禁止访问资源,这取决于如何设置它。

特性的影响 Semaphore

以下是信号旗的特点:

  • 它是一种可用于提供任务同步的机制。
  • 它是一种低级同步机制。
  • Semaphore 将始终保持非负整数值。
  • Semaphore 可以使用测试操作和中断来实现,这应该使用文件描述符来执行。

有哪些 Semaphores

两种常见的信号灯类型是:

  • 计数信号量
  • 二元信号量

计数 Semaphores

这类 Semaphore 使用计数来帮助任务被多次获取或释放。如果初始计数为 0,则计数信号量应创建在不可用状态下。

计数 Semaphores

然而,如果计数 > 0,则信号量在可用状态下创建,并且它拥有的令牌数等于它的计数。

二进制 Semaphores

二元信号量与计数信号量非常相似,但它们的值仅限于 0 和 1。在这种类型的信号量中,等待操作仅在信号量 = 1 时有效,而信号操作在信号量 = 0 时成功。它比计数信号量更容易实现。

二进制 Semaphores

示例 Semaphore

下面给出的程序是一个逐步实现,其中涉及信号量的使用和声明。

Shared var mutex: semaphore = 1;
Process i
    begin
    .
    .
    P(mutex);
    execute CS;
    V(mutex);
    .
    .
    End;

等待 Signal Opera在 Semaphores

这两个操作都用于实现 进程同步.这个信号量操作的目的是为了获得互斥。

等待 OperaTION

这种信号量操作可帮助您控制任务进入临界区。但是,如果 wait 的值为正,则 wait 参数 X 的值会减少。如果为负值或零值,则不执行任何操作。它也被称为 P(S) 操作。

信号量值减少至负值后,命令将被暂停,直到满足所需条件为止。

P(S)
{
    while (S<=0);
    S--;
}

Signal 操作

这类 Semaphore 操作用于控制任务从临界区退出。它有助于将参数的值增加 1,表示为 V(S)。

P(S)
{
    while (S>=0);
    S++;
}

计数 Semaphore 与二进制 Semaphore

这里,是计数和二进制信号量之间的一些主要区别:

计数 Semaphore 二进制 Semaphore
无互斥 相互排斥
任意整数值 值仅 0 和 1
多个插槽 只有一个插槽
提供一套流程 它具有互斥机制。

之间的区别 Semaphore 与互斥锁

下表比较了 带互斥锁的信号灯 在多个参数方面:

参数 Semaphore 互斥
机制 它是一种信号机制。 这是一种锁定机制。
数据类型 Semaphore 是一个整型变量。 互斥锁只是一个对象。
修改 等待和信号操作可以修改信号量。 它仅可由可能请求或释放资源的进程修改。
资源管理 如果没有空闲资源,则进程需要资源,并执行等待操作。它应该等待,直到信号量的计数大于 0。 如果被锁定,进程必须等待。进程应保存在队列中。仅当互斥锁解锁时才需要访问该队列。
Thread 您可以有多个程序线程。 互斥锁中可以有多个程序线程,但不能同时存在。
所有权 任何释放或获取资源的过程都可以改变该值。 对象锁仅由获得该锁的进程释放。
类型 有哪些 Semaphore 正在计数信号量和二进制信号量。 Mutex 没有子类型。
操作 Semaphore 使用wait()和signal()操作来修改值。 互斥对象被锁定或解锁。
资源占用 如果所有资源都在使用,则信号量被占用,请求资源的进程执行wait()操作并阻塞自身,直到信号量计数变为>1。 如果对象已被锁定,则请求资源的进程将等待,并且会被系统排队,直到锁被释放。

的优点 Semaphores

以下是使用的优点/好处 Semaphore:

  • 它允许多个线程访问临界区。
  • Semaphore与机器无关。
  • Semaphore是在微内核的机器独立代码中实现的。
  • 它们不允许多个进程进入临界区。
  • 由于信号量处于忙等待状态,因此不会浪费进程时间和资源。
  • 它们是与机器无关的,应该在微内核的机器无关代码中运行。
  • 它们允许灵活地管理资源。

缺点 Semaphores

以下是信号旗的缺点/不足之处:

  • 信号量的最大限制之一是优先级反转。
  • 操作系统必须保持 track 代表所有等待和信号量调用。
  • 它们的使用从未被强制执行,而只是按照惯例。
  • 为了避免信号量中的死锁,Wait 和 Signal 操作需要按照正确的顺序执行。
  • Semaphore 编程很复杂,因此有可能无法实现互斥。
  • 这也不是一种适合大规模使用的实用方法,因为使用它们会导致模块化的丧失。
  • Semaphore 更容易出现程序员错误。
  • 可能导致 僵局 或由于程序员错误而违反互斥规定。

常见问题

艾兹格·迪克斯特拉于 1965 年引入了信号量。等待和信号操作也称为 P 和 V,源自荷兰语单词 proberen(测试)和 verhogen(增加)。

纯计数信号量的值始终为非负数,但许多实现允许其值为负数。此时,信号量的大小等于信号量队列中等待的进程数。

Semaphore它们协调经典的并发问题,例如生产者-消费者(有界缓冲区)和读写者问题。它们控制对有限数量的相同资源的访问,从而保护共享数据。

互斥锁具有所有权,因此只有锁定它的线程才能解锁它。二进制信号量没有所有权,因此任何线程都可以向其发送信号。它们并不相同。

当低优先级线程持有高优先级线程需要的信号量时,就会发生优先级反转,迫使高优先级线程等待。优先级继承协议可以减少这种情况的发生。

大多数现代平台都提供信号量:POSIX 中的 sem_t,C 语言中的 sem_t。 Semaphore 上课 Java以及螺纹连接。Semaphore in Python开发者很少从零开始构建一个。

机器学习可以分析执行情况 trac预测争用、调整计数信号量持有的许可数量以及标记可能的死锁,帮助ping 工程师设计更安全的并发方案。

是的。像 GitHub Copilot 这样的 AI 助手可以生成等待和信号模板,建议锁的顺序,并解释竞态条件。 Rev仔细查看输出结果,因为细微的死锁很容易隐藏。

总结一下这篇文章: