You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++20二进制信号量超出最大值仍可多次获取?求解释

C++20 std::binary_semaphore多次release后acquire不阻塞的原因解析

你的测试结果并非C标准规定的行为,这是**GCC 11版本中libstdc的实现bug**。

标准对binary_semaphore的明确要求

std::binary_semaphore是std::counting_semaphore<1>的类型别名,核心规则如下:

  • 内部计数的上限为max()返回的1,任何操作都不能让计数超过这个值。
  • 调用release()(无参数时等价于release(1))时,如果当前计数加1会超过上限,计数会被截断为上限值(即1),不会继续累加。

按照标准,你的测试代码应产生的行为:

  1. 初始化sem为0,计数=0。
  2. 第一次release():计数从0变为1(未超过上限)。
  3. 第二次release():计数保持1(因加1会突破上限,被截断)。
  4. 第一次acquire():计数从1变为0。
  5. 第二次acquire():此时计数为0,调用会永久阻塞,程序无法正常返回。

测试结果异常的原因

GCC 11的libstdc++库对std::binary_semaphore的实现存在缺陷,未正确限制计数不超过max()值。多次调用release()会让计数突破上限(比如你的测试中计数被累加到了2),导致后续两次acquire()都能顺利递减计数,程序正常结束。

解决方式

该bug在GCC 12及以上版本的libstdc++中已被修复。你可以升级编译器到GCC 12或更高版本,重新编译运行代码,就能看到符合标准的阻塞行为。

内容的提问来源于stack exchange,提问作者DeZee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 00:57:27