我编写了一个boost :: thread应用程序,我可能会根据valgrind / helgrind报告获得一些竞争条件.我想确定这些比赛的原因.
该计划是:
#include <boost/thread.hpp>
boost::mutex myMutex;
boost::condition_variable myConditionalVariable;
bool functionWasRun = false;
void function()
{
{
boost::lock_guard<boost::mutex> lock(myMutex);
functionWasRun = true;
}
myConditionalVariable.notify_one();
//doSomething1();
}
int main()
{
boost::thread pThread(function);
//Wait for the thread to start
boost::unique_lock<boost::mutex> lock(myMutex);
while (!functionWasRun)
myConditionalVariable.wait(lock);
//doSomething2();
pThread.join();
}
对于这个简单的程序,valgrind / helgrind报告了以下错误:
06001
请问您能帮我确定如何修复此程序?
该程序在Ubuntu 14.04LTS,x86_64,gcc ver上运行. 4.8.2,libboost v.1.54,valgrind 3.10.0.我的原始程序是一个使用ActiveObject类的复杂应用程序,它已经被剥离到最低限度以查看竞争条件模式.
此线程可能看起来类似于Debug boost::thread application, high false positive rate,但涉及条件变量/互斥量.
最佳答案 好消息是你的程序是正确的. valgrind报告的所有比赛都是误报(尽管在加入线程之前考虑解锁互斥锁 – 以后可能会让你头疼).
我有OSX10.10所以必须从最新的trunk创建valgrind才能尝试这个.
这是它给我的东西(下面的截断输出)
我用std :: thread / std :: mutex等重写了程序,并得到了类似的结果.
截断输出:
==79537== Helgrind, a thread error detector
==79537== Copyright (C) 2007-2013, and GNU GPL'd, by OpenWorks LLP et al.
==79537== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
==79537== Command: Build/Products/Debug/cpprules
==79537==
--79537-- Build/Products/Debug/cpprules:
--79537-- dSYM directory is missing; consider using --dsymutil=yes
--79537-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option
--79537-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 2 times)
--79537-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 4 times)
==79537== ---Thread-Announcement------------------------------------------
==79537==
==79537== Thread #2 was created
==79537== at 0x10048D7EE: __bsdthread_create (in /usr/lib/system/libsystem_kernel.dylib)
==79537== by 0x10003FC75: boost::thread::start_thread_noexcept() (in /usr/local/lib/libboost_thread.dylib)
==79537== by 0x10000134E: main (in Build/Products/Debug/cpprules)
==79537==
==79537== ---Thread-Announcement------------------------------------------
==79537==
==79537== Thread #1 is the program's root thread
==79537==
==79537== ----------------------------------------------------------------
==79537==
==79537== Possible data race during read of size 4 at 0x1005AA2D8 by thread #2
==79537== Locks held: none
==79537== at 0x10058FFCF: spin_lock (in /usr/lib/system/libsystem_platform.dylib)
==79537== by 0x1005A3278: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1005A14B0: thread_start (in /usr/lib/system/libsystem_pthread.dylib)
==79537==
==79537== This conflicts with a previous write of size 4 by thread #1
==79537== Locks held: none
==79537== at 0x10058FFDF: spin_unlock (in /usr/lib/system/libsystem_platform.dylib)
==79537== by 0x10003FC75: boost::thread::start_thread_noexcept() (in /usr/local/lib/libboost_thread.dylib)
==79537== by 0x10000134E: main (in Build/Products/Debug/cpprules)
==79537== Address 0x1005aa2d8 is in the Data segment of /usr/lib/system/libsystem_pthread.dylib
==79537==
==79537== ----------------------------------------------------------------
==79537==
==79537== Possible data race during read of size 4 at 0x103DEB010 by thread #2
==79537== Locks held: none
==79537== at 0x1005A3293: _pthread_body (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1005A3278: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1005A14B0: thread_start (in /usr/lib/system/libsystem_pthread.dylib)
==79537==
==79537== This conflicts with a previous write of size 4 by thread #1
==79537== Locks held: none
==79537== at 0x1005A30D8: pthread_create (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x10003FC75: boost::thread::start_thread_noexcept() (in /usr/local/lib/libboost_thread.dylib)
==79537== by 0x10000134E: main (in Build/Products/Debug/cpprules)
==79537== Address 0x103deb010 is in a rw- mapped file segment
==79537==
==79537== ----------------------------------------------------------------
==79537==
==79537== Possible data race during write of size 4 at 0x103DEB010 by thread #2
==79537== Locks held: none
==79537== at 0x1005A329B: _pthread_body (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1005A3278: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1005A14B0: thread_start (in /usr/lib/system/libsystem_pthread.dylib)
==79537==
==79537== This conflicts with a previous write of size 4 by thread #1
==79537== Locks held: none
==79537== at 0x1005A30D8: pthread_create (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x10003FC75: boost::thread::start_thread_noexcept() (in /usr/local/lib/libboost_thread.dylib)
==79537== by 0x10000134E: main (in Build/Products/Debug/cpprules)
==79537== Address 0x103deb010 is in a rw- mapped file segment
==79537==
==79537== ----------------------------------------------------------------
==79537==
==79537== Possible data race during write of size 4 at 0x1005AA2D8 by thread #2
==79537== Locks held: none
==79537== at 0x10058FFDF: spin_unlock (in /usr/lib/system/libsystem_platform.dylib)
==79537== by 0x1005A3278: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1005A14B0: thread_start (in /usr/lib/system/libsystem_pthread.dylib)
==79537==
==79537== This conflicts with a previous write of size 4 by thread #1
==79537== Locks held: none
==79537== at 0x10058FFDF: spin_unlock (in /usr/lib/system/libsystem_platform.dylib)
==79537== by 0x10003FC75: boost::thread::start_thread_noexcept() (in /usr/local/lib/libboost_thread.dylib)
==79537== by 0x10000134E: main (in Build/Products/Debug/cpprules)
==79537== Address 0x1005aa2d8 is in the Data segment of /usr/lib/system/libsystem_pthread.dylib
==79537==
==79537== ----------------------------------------------------------------
==79537==
==79537== Possible data race during read of size 4 at 0x10004D118 by thread #2
==79537== Locks held: none
==79537== at 0x100048451: boost::thread_detail::enter_once_region(boost::once_flag&) (in /usr/local/lib/libboost_thread.dylib)
==79537== by 0x10003FA54: boost::detail::set_current_thread_data(boost::detail::thread_data_base*) (in /usr/local/lib/libboost_thread.dylib)
==79537== by 0x10003FD6C: boost::(anonymous namespace)::thread_proxy(void*) (in /usr/local/lib/libboost_thread.dylib)
==79537== by 0x1005A32FB: _pthread_body (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1005A3278: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1005A14B0: thread_start (in /usr/lib/system/libsystem_pthread.dylib)
==79537==
==79537== This conflicts with a previous write of size 4 by thread #1
==79537== Locks held: none
==79537== at 0x10004854A: boost::thread_detail::commit_once_region(boost::once_flag&) (in /usr/local/lib/libboost_thread.dylib)
==79537== by 0x10003F9F4: boost::detail::get_current_thread_data() (in /usr/local/lib/libboost_thread.dylib)
==79537== by 0x10000139F: main (in Build/Products/Debug/cpprules)
==79537== Address 0x10004d118 is in the Data segment of /usr/local/lib/libboost_thread.dylib
==79537==
==79537== ----------------------------------------------------------------
==79537==
==79537== Possible data race during read of size 8 at 0x10004D120 by thread #2
==79537== Locks held: none
==79537== at 0x10003FA78: boost::detail::set_current_thread_data(boost::detail::thread_data_base*) (in /usr/local/lib/libboost_thread.dylib)
==79537== by 0x10003FD6C: boost::(anonymous namespace)::thread_proxy(void*) (in /usr/local/lib/libboost_thread.dylib)
==79537== by 0x1005A32FB: _pthread_body (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1005A3278: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1005A14B0: thread_start (in /usr/lib/system/libsystem_pthread.dylib)
==79537==
==79537== This conflicts with a previous write of size 8 by thread #1
==79537== Locks held: none
==79537== at 0x1005A1618: pthread_key_create (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x10003F9E8: boost::detail::get_current_thread_data() (in /usr/local/lib/libboost_thread.dylib)
==79537== by 0x10000139F: main (in Build/Products/Debug/cpprules)
==79537== Address 0x10004d120 is in the Data segment of /usr/local/lib/libboost_thread.dylib
==79537==
==79537== ----------------------------------------------------------------
==79537==
==79537== Possible data race during read of size 8 at 0x1005AC448 by thread #2
==79537== Locks held: none
==79537== at 0x1005A269E: pthread_setspecific (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1005A32FB: _pthread_body (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1005A3278: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1005A14B0: thread_start (in /usr/lib/system/libsystem_pthread.dylib)
==79537==
==79537== This conflicts with a previous write of size 8 by thread #1
==79537== Locks held: none
==79537== at 0x1005A1614: pthread_key_create (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x10003F9E8: boost::detail::get_current_thread_data() (in /usr/local/lib/libboost_thread.dylib)
==79537== by 0x10000139F: main (in Build/Products/Debug/cpprules)
==79537== Address 0x1005ac448 is in the Data segment of /usr/lib/system/libsystem_pthread.dylib
==79537==
==79537== ----------------------------------------------------------------
==79537==
==79537== Possible data race during write of size 1 at 0x100009D48 by thread #2
==79537== Locks held: none
==79537== at 0x100000F49: function() (in Build/Products/Debug/cpprules)
==79537== by 0x10003FD79: boost::(anonymous namespace)::thread_proxy(void*) (in /usr/local/lib/libboost_thread.dylib)
==79537== by 0x1005A32FB: _pthread_body (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1005A3278: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1005A14B0: thread_start (in /usr/lib/system/libsystem_pthread.dylib)
==79537==
==79537== This conflicts with a previous read of size 1 by thread #1
==79537== Locks held: none
==79537== at 0x10000138D: main (in Build/Products/Debug/cpprules)
==79537== Address 0x100009d48 is in the Data segment of Build/Products/Debug/cpprules
==79537==
==79537== ----------------------------------------------------------------
==79537==
==79537== Possible data race during write of size 8 at 0x100009D28 by thread #2
==79537== Locks held: none
==79537== at 0x1005A4099: _pthread_cond_updateval (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1005A294D: _pthread_cond_signal (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x100000F77: function() (in Build/Products/Debug/cpprules)
==79537== by 0x10003FD79: boost::(anonymous namespace)::thread_proxy(void*) (in /usr/local/lib/libboost_thread.dylib)
==79537== by 0x1005A32FB: _pthread_body (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1005A3278: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1005A14B0: thread_start (in /usr/lib/system/libsystem_pthread.dylib)
==79537==
==79537== This conflicts with a previous write of size 8 by thread #1
==79537== Locks held: none
==79537== at 0x1005A3DE1: _pthread_cond_wait (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1000014AA: main (in Build/Products/Debug/cpprules)
==79537== Address 0x100009d28 is in the Data segment of Build/Products/Debug/cpprules
==79537==
==79537== ----------------------------------------------------------------
==79537==
==79537== Possible data race during read of size 8 at 0x1005AC448 by thread #2
==79537== Locks held: none
==79537== at 0x1005A4791: _pthread_tsd_cleanup (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1005A44E4: _pthread_exit (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1005A3306: _pthread_body (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1005A3278: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1005A14B0: thread_start (in /usr/lib/system/libsystem_pthread.dylib)
==79537==
==79537== This conflicts with a previous write of size 8 by thread #1
==79537== Locks held: none
==79537== at 0x1005A1614: pthread_key_create (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x10003F9E8: boost::detail::get_current_thread_data() (in /usr/local/lib/libboost_thread.dylib)
==79537== by 0x10000139F: main (in Build/Products/Debug/cpprules)
==79537== Address 0x1005ac448 is in the Data segment of /usr/lib/system/libsystem_pthread.dylib
==79537==
…
==79537== ----------------------------------------------------------------
==79537==
==79537== Possible data race during write of size 8 at 0x100009C98 by thread #1
==79537== Locks held: none
==79537== at 0x1005A37DD: pthread_mutex_destroy (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x100005D50: boost::mutex::~mutex() (in Build/Products/Debug/cpprules)
==79537== by 0x1003A38EC: __cxa_finalize_ranges (in /usr/lib/system/libsystem_c.dylib)
==79537== by 0x1003A3BEF: exit (in /usr/lib/system/libsystem_c.dylib)
==79537== by 0x1002F05CF: start (in /usr/lib/system/libdyld.dylib)
==79537==
==79537== This conflicts with a previous read of size 8 by thread #2
==79537== Locks held: none
==79537== at 0x1005A1655: _pthread_mutex_lock (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x100000EBB: function() (in Build/Products/Debug/cpprules)
==79537== by 0x10003FD79: boost::(anonymous namespace)::thread_proxy(void*) (in /usr/local/lib/libboost_thread.dylib)
==79537== by 0x1005A32FB: _pthread_body (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1005A3278: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib)
==79537== by 0x1005A14B0: thread_start (in /usr/lib/system/libsystem_pthread.dylib)
==79537== Address 0x100009c98 is in the Data segment of Build/Products/Debug/cpprules
==79537==
==79537==
==79537== For counts of detected and suppressed errors, rerun with: -v
==79537== Use --history-level=approx or =none to gain increased speed, at
==79537== the cost of reduced accuracy of conflicting-access information
==79537== ERROR SUMMARY: 34 errors from 33 contexts (suppressed: 0 from 0)