VSTest的Logger::WriteMessage是否非线程安全?
多线程调用VSTest Logger::WriteMessage导致的线程安全问题分析与解决
问题根源
你遇到的所有异常和统计错误,本质是**Logger::WriteMessage不具备线程安全性**。虽然官方文档未明确说明,但从复现的现象来看,该API的内部实现没有做并发访问的同步控制:
- 多线程同时写入日志缓冲区时,会触发竞态条件,破坏内部数组结构,导致
Source array was not long enough...的越界异常 - 并发操作还会干扰测试框架的计数逻辑,造成实际测试数与统计数不符、无失败记录但通过次数不足的问题
解决方案
必须对Logger::WriteMessage的调用做同步控制,使用互斥锁确保同一时间只有一个线程访问该API。修改后的示例代码如下:
#include <thread> #include <vector> #include <mutex> #include "CppUnitTest.h" using namespace std::chrono_literals; using Microsoft::VisualStudio::CppUnitTestFramework::Logger; namespace NamespaceFoo { TEST_CLASS (ClassFoo) { private: static inline std::mutex logger_mutex; // 静态互斥锁,所有测试方法共享 #define TEST(NAME) \ TEST_METHOD (NAME) { \ std::vector<std::jthread> threads; \ for (int i = 0; i < 10; i++) \ threads.emplace_back([] { \ std::this_thread::sleep_for(100ms); \ std::lock_guard<std::mutex> lock(logger_mutex); \ Logger::WriteMessage("Message"); \ }); \ } TEST(A) TEST(B) TEST(C) TEST(D) TEST(E) TEST(F) TEST(G) TEST(H) TEST(I) TEST(J) TEST(K) TEST(L) TEST(M) TEST(N) TEST(O) TEST(P) TEST(Q) TEST(R) TEST(S) TEST(T) TEST(U) TEST(V) TEST(W) TEST(X) TEST(Y) TEST(Z) }; } // namespace NamespaceFoo
验证说明
你当前使用mutex锁缓解问题的做法完全正确,这是消除该类并发问题的必要手段。同步后,竞态条件被彻底消除,测试框架的内部状态不会被破坏,所有异常和统计错误都会消失。
内容的提问来源于stack exchange,提问作者bers
相关产品推荐
相关产品推荐

