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

MingW-w64中counting_semaphore引发死锁问题的技术问询

MingW-w64编译的C++计数信号量程序出现死锁,Linux/VS编译正常

问题现象

我编写的多线程程序,在Linux(g12.2.0、clang15.0.2-1)和Windows Visual Studio 2022 17.4.2环境下能稳定运行,但使用MingW-w64编译后频繁触发死锁——无论是否开启优化选项,通常循环不到10000次就会阻塞。

进一步调试发现,一段使用std::counting_semaphore的极简复现代码也存在相同问题。如果将acquire()替换为try_acquire_for(chrono::milliseconds(1000)),MingW-w64环境下程序就能永久运行无停顿。

复现代码

#include <iostream>
#include <thread>
#include <semaphore>
using namespace std;

std::counting_semaphore<3> cs1(0), cs2(0);

int main(int argc, char const *argv[])
{
    thread th(
        []()
        {
            for (int j = 0;; j--)
            {
                cs1.release();
                printf("%d\n", j);
                cs2.acquire();
            }
        });

    for (int i = 0;; i++)
    {
        cs2.release();
        printf("%d\n", i);
        cs1.acquire();
    }

    th.join();

    return 0;
}

死锁时的输出片段

...
-804
805
806
-805
-806
-807
-808
807
808
809
810
-809
-810
-811
811
812
(blocked)

从输出可见,主线程执行print(i=812)前的cs2.release()操作,并未唤醒子线程中print(j=-811)后等待cs2.acquire()的逻辑。

MingW-w64环境信息

MingW-w64-g和MingW-w64-clang均存在此问题,使用的是winlibs个人构建版本,线程与异常模型为POSIX-seh:

winlibs personal build version gcc-12.2.0-llvm-14.0.6-mingw-w64ucrt-10.0.0-r2

This is the winlibs 64-bit standalone build of:
- GCC 12.2.0
- GDB 12.1
- LLVM/Clang/LLD/LLDB 14.0.6
- MinGW-w64 10.0.0 (linked with ucrt)
- GNU Binutils 2.39
- GNU Make 4.3
- PExports 0.47
- dos2unix 7.4.3
- Yasm 1.3.0
- NASM 2.15.05
- JWasm 2.12pre
- ninja 1.11.0
- doxygen 1.9.5

This build was compiled with GCC 12.2.0 and packaged on 2022-08-28.

推测方向

目前无法确定问题根源:

  • 代码逻辑在Linux和VS的标准库实现下能稳定运行,暂未发现明显线程不安全因素;
  • 替换为带超时的try_acquire_for后,MingW-w64环境下程序恢复正常,推测原始acquire的唤醒逻辑可能存在实现缺陷。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 16:20:36