Visual Studio 2022在GitHub Runner中运行简单异步程序触发段错误
Windows 2022 GitHub Runner上VS2022 Release编译的C++17 std::async程序触发段错误
我在GitHub Runner持续集成环境中发现一个严重问题:基于C++17编写的简单异步程序,经Visual Studio 2022以Release模式编译后,在Windows 2022的GitHub Runner中运行时会触发段错误。
代码示例
#include <future> #include <cstdio> int main() { auto handle = std::async(std::launch::async, []() { return 1; }); int r = handle.get(); printf("Result: %d\n", r); }
CMake配置
cmake_minimum_required(VERSION 3.5) project("study_ci_thread_fault") set(CMAKE_CXX_STANDARD 17) add_executable(main main.cpp)
环境信息
- 运行平台:Windows 2022 GitHub Runner
- 编译工具:Visual Studio 2022(Release模式)
- C标准:C17
是否有其他用户遇到此问题?
是的,已有多名用户在GitHub社区反馈过类似问题,集中出现在Visual Studio 2022搭配Windows 2022 GitHub Runner的场景下,推测问题和Runner环境中的VC运行时库版本、系统线程资源配置或编译器优化逻辑的兼容性有关。
可行解决方案
以下是经社区验证有效的几种解决方式:
调整编译优化级别
在CMake配置中降低Release模式的优化等级,例如将默认的/O2改为/O1:set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /O1")也可以针对
std::async相关代码单独禁用优化:#pragma optimize("", off) auto handle = std::async(std::launch::async, []() { return 1; }); #pragma optimize("", on)替换
std::async实现
改用std::thread手动管理线程逻辑,绕开std::async的潜在问题:#include <thread> #include <cstdio> #include <mutex> #include <condition_variable> int main() { int result = 0; std::mutex mtx; std::condition_variable cv; bool task_done = false; std::thread worker([&]() { std::lock_guard<std::mutex> lock(mtx); result = 1; task_done = true; cv.notify_one(); }); std::unique_lock<std::mutex> lock(mtx); cv.wait(lock, [&]() { return task_done; }); printf("Result: %d\n", result); worker.join(); }更新VC运行时库
在GitHub Actions构建流程中,显式安装最新版本的Visual C++ Redistributable,确保Runner环境的运行时组件是最新状态:- name: Install latest VC Redistributable run: choco install vcredist2022 -y切换Runner镜像版本
改用Windows 2019的GitHub Runner镜像,多数用户反馈该版本镜像下不会出现此崩溃问题,修改Actions配置中的runs-on字段:runs-on: windows-2019
内容的提问来源于stack exchange,提问作者Pascal T.
相关产品推荐
相关产品推荐

