经过几天痛苦的调试,我可以用这个小程序重现我的单元测试中的一个错误:
#include <iostream> #include <vector> #include <condition_variable> #include <mutex> #include <thread> #include <chrono> #include <new> int main(){ try{ for(size_t j=0;j<100;++j){ std::cout<<j<<std::endl; std::mutex mutex; std::unique_ptr<std::condition_variable>cv; std::vector<std::thread>v(10); auto wait=[&](size_t i){ std::unique_lock<std::mutex>ul(mutex); if(!cv){cv=std::make_unique<std::condition_variable>();} cv->wait_for(ul,std::chrono::milliseconds(i*10)); }; for(size_t i=0;i<v.size();++i){v[i]=std::thread(wait,i);} for(size_t i=0;i<v.size();++i){v[i].join();}}} catch(...){ std::cout<<"Exception"<<std::endl; std::abort();} }
当我用lmcheck编译时:
g++-4.9.2 -lmcheck -std=c++1y -pthread /home/Arnaud/Test.cpp -o Test
程序在分配块之前运行并停止,内存被破坏
我可以在多台机器上重现这一点,并使用gcc 4.9.2和gcc 5.1.这段代码有什么问题?
解决方法
根据
this documentation,mcheck不是线程安全的.
看起来像链接-lmcheck会添加调用mcheck的分配挂钩,这意味着在没有额外同步的情况下从多个线程分配和释放内存不再安全.