gpt4 book ai didi

c++ - std::thread 的 drd 和 helgrind 支持的当前状态

转载 作者:可可西里 更新时间:2023-11-01 15:05:50 28 4
gpt4 key购买 nike

当我将我的代码转换为 C++11 时,我非常想将我的 pthread 代码转换为 std::thread。但是,我似乎在 drd 和 helgrind 中的非常简单的程序中遇到了错误的竞争条件。

#include <thread>

int main(int argc, char** argv)
{
std::thread t( []() { } );
t.join();
return 0;
}

Helgrind 输出片段 - 我在 drd 中也遇到了类似的错误,在 Ubuntu 11.11 amd64 上使用 gcc 4.6.1、valgrind 3.7.0。

我的问题是:

  • 健全性检查:我做错了什么吗?其他人是否在简单的 std::thread 程序上收到类似的错误报告?
  • std::thread 的当前用户使用什么来检测竞争条件?

我不愿意将大量代码从 pthread 移植到 std::thread,直到 helgrind/drd 等一些关键工具 catch 来。

==19347== ---Thread-Announcement------------------------------------------
==19347==
==19347== Thread #1 is the program's root thread
==19347==
==19347== ---Thread-Announcement------------------------------------------
==19347==
==19347== Thread #2 was created
==19347== at 0x564C85E: clone (clone.S:77)
==19347== by 0x4E37E7F: do_clone.constprop.3 (createthread.c:75)
==19347== by 0x4E39604: pthread_create@@GLIBC_2.2.5 (createthread.c:256)
==19347== by 0x4C2B3DA: pthread_create_WRK (hg_intercepts.c:255)
==19347== by 0x4C2B55E: pthread_create@* (hg_intercepts.c:286)
==19347== by 0x50BED02: std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==19347== by 0x400D51: _ZNSt6threadC1IZ4mainEUlvE_IEEEOT_DpOT0_ (in /mnt/home/kfeng/dev/robolab/cpp/sbx/sandbox)
==19347== by 0x400C60: main (in /mnt/home/kfeng/dev/robolab/cpp/sbx/sandbox)
==19347==
==19347== ----------------------------------------------------------------
==19347==
==19347== Possible data race during write of size 8 at 0x5B8E060 by thread #1
==19347== Locks held: none
==19347== at 0x40165E: _ZNSt6thread5_ImplISt12_Bind_resultIvFZ4mainEUlvE_vEEED1Ev (in /mnt/home/kfeng/dev/robolab/cpp/sbx/sandbox)
==19347== by 0x401895: _ZNKSt19_Sp_destroy_inplaceINSt6thread5_ImplISt12_Bind_resultIvFZ4mainEUlvE_vEEEEEclEPS6_ (in /mnt/home/kfeng/dev/robolab/cpp/sbx/sandbox)
==19347== by 0x4016D8: _ZNSt19_Sp_counted_deleterIPNSt6thread5_ImplISt12_Bind_resultIvFZ4mainEUlvE_vEEEESt19_Sp_destroy_inplaceIS6_ESaIS6_ELN9__gnu_cxx12_Lock_policyE2EE10_M_disposeEv (in /mnt/home/kfeng/dev/robolab/cpp/sbx/sandbox)
==19347== by 0x401B83: std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() (in /mnt/home/kfeng/dev/robolab/cpp/sbx/sandbox)
==19347== by 0x401B3E: std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() (in /mnt/home/kfeng/dev/robolab/cpp/sbx/sandbox)
==19347== by 0x401A93: std::__shared_ptr<std::thread::_Impl_base, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() (in /mnt/home/kfeng/dev/robolab/cpp/sbx/sandbox)
==19347== by 0x401AAD: std::shared_ptr<std::thread::_Impl_base>::~shared_ptr() (in /mnt/home/kfeng/dev/robolab/cpp/sbx/sandbox)
==19347== by 0x400D5D: _ZNSt6threadC1IZ4mainEUlvE_IEEEOT_DpOT0_ (in /mnt/home/kfeng/dev/robolab/cpp/sbx/sandbox)
==19347== by 0x400C60: main (in /mnt/home/kfeng/dev/robolab/cpp/sbx/sandbox)
==19347==
==19347== This conflicts with a previous read of size 8 by thread #2
==19347== Locks held: none
==19347== at 0x50BEABE: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==19347== by 0x4C2B547: mythread_wrapper (hg_intercepts.c:219)
==19347== by 0x4E38EFB: start_thread (pthread_create.c:304)
==19347== by 0x564C89C: clone (clone.S:112)
==19347==
==19347== Address 0x5B8E060 is 32 bytes inside a block of size 64 alloc'd
==19347== at 0x4C29059: operator new(unsigned long) (vg_replace_malloc.c:287)
==19347== by 0x4012E9: _ZN9__gnu_cxx13new_allocatorISt23_Sp_counted_ptr_inplaceINSt6thread5_ImplISt12_Bind_resultIvFZ4mainEUlvE_vEEEESaIS8_ELNS_12_Lock_policyE2EEE8allocateEmPKv (in /mnt/home/kfeng/dev/robolab/cpp/sbx/sandbox)
==19347== by 0x40117C: _ZNSt14__shared_countILN9__gnu_cxx12_Lock_policyE2EEC1INSt6thread5_ImplISt12_Bind_resultIvFZ4mainEUlvE_vEEEESaISA_EIS9_EEESt19_Sp_make_shared_tagPT_RKT0_DpOT1_ (in /mnt/home/kfeng/dev/robolab/cpp/sbx/sandbox)
==19347== by 0x4010B9: _ZNSt12__shared_ptrINSt6thread5_ImplISt12_Bind_resultIvFZ4mainEUlvE_vEEEELN9__gnu_cxx12_Lock_policyE2EEC1ISaIS6_EIS5_EEESt19_Sp_make_shared_tagRKT_DpOT0_ (in /mnt/home/kfeng/dev/robolab/cpp/sbx/sandbox)
==19347== by 0x401063: _ZNSt10shared_ptrINSt6thread5_ImplISt12_Bind_resultIvFZ4mainEUlvE_vEEEEEC1ISaIS6_EIS5_EEESt19_Sp_make_shared_tagRKT_DpOT0_ (in /mnt/home/kfeng/dev/robolab/cpp/sbx/sandbox)
==19347== by 0x401009: _ZSt15allocate_sharedINSt6thread5_ImplISt12_Bind_resultIvFZ4mainEUlvE_vEEEESaIS6_EIS5_EESt10shared_ptrIT_ERKT0_DpOT1_ (in /mnt/home/kfeng/dev/robolab/cpp/sbx/sandbox)
==19347== by 0x400EF7: _ZSt11make_sharedINSt6thread5_ImplISt12_Bind_resultIvFZ4mainEUlvE_vEEEEIS5_EESt10shared_ptrIT_EDpOT0_ (in /mnt/home/kfeng/dev/robolab/cpp/sbx/sandbox)
==19347== by 0x400E17: _ZNSt6thread15_M_make_routineISt12_Bind_resultIvFZ4mainEUlvE_vEEEESt10shared_ptrINS_5_ImplIT_EEEOS7_ (in /mnt/home/kfeng/dev/robolab/cpp/sbx/sandbox)
==19347== by 0x400D2B: _ZNSt6threadC1IZ4mainEUlvE_IEEEOT_DpOT0_ (in /mnt/home/kfeng/dev/robolab/cpp/sbx/sandbox)
==19347== by 0x400C60: main (in /mnt/home/kfeng/dev/robolab/cpp/sbx/sandbox)
==19347==
==19347== ----------------------------------------------------------------
==19347==

最佳答案

std::thread 在内部使用共享指针。您看到的是该共享指针对象的引用计数的误报。您可以通过在每个源文件中的 C++ header 包含指令之前添加如下所示的四行代码来避免这些误报。注意:这仅适用于 gcc 4.6.0 或更高版本中包含的 libstdc++ 版本。

#include <valgrind/drd.h>
#define _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(addr) ANNOTATE_HAPPENS_BEFORE(addr)
#define _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(addr) ANNOTATE_HAPPENS_AFTER(addr)
#define _GLIBCXX_EXTERN_TEMPLATE -1

有关更多信息,另请参阅 libstdc++ 手册 (http://gcc.gnu.org/onlinedocs/libstdc++/manual/debug.html) 中的数据争用搜索部分。

关于c++ - std::thread 的 drd 和 helgrind 支持的当前状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8393777/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com