C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了c – 来自std :: set insert()和find()的写入数据竞争?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_696_2@
为了试验线程消毒器,我创建了一个微小的C程序,其目的包含数据竞争.确实,tsan确实检测到错误,太棒了!但是我对生成的消息感到困惑……

>它报告了一个写 – 写数据竞赛,我本来期望读写竞赛.我希望find()不会写入我的容器中.如果我尝试进一步调整set :: find()的const版本进行进一步的小代码调整,那么相同的写 – 写比赛似乎仍然存在.
>它显示了在同一地址的4字节原子写入和8字节写入之间的写入冲突.容器类中的相同字段由两个这样的不同访问类型访问似乎很奇怪.

是否可以选择使用不写入STL容器的const find()?

这是经过测试的C程序:

/*****************************************************************************
 * small example with an inter-thread data race that is not obvIoUs.
 * the error is a consequence of the non-threadsafeness of the STL containers.
 * Threading is created through portable C++11 constructs.
 * Tsan does detect the data race(?).
 *
 * Compile with one of:
 * g++-4.8 -std=c++11 -g -Wall -o race-stl11b race-stl11b.cc -pthread
 * g++-4.8 -std=c++11 -g -Wall -fsanitize=thread -fPIE -o race-stl11b-tsan race-stl11b.cc -ltsan -pie -pthread
 ******************************************************************************/

#include <iostream>
#include <thread>
#include <set>

int main()
{
    // create an empty bucket
    std::set<int> bucket;

    // Use a BACkground task to insert value '5' in the bucket 
    std::thread t([&](){ bucket.insert(5); });

    // check if value '3' is in the bucket (not expected :-)
    bool contains3 = bucket.find(3) != bucket.cend();
    std::cout << "Foreground find done: " << contains3 << std::endl;

    // Wait for the BACkground thread to finish
    t.join();

    // verify that value '5' did arrive in the bucket
    bool contains5 = bucket.find(5) != bucket.cend();
    std::cout << "BACkground insert: " << contains5 << std::endl;

    return 0;
}

这是tsan输出(的一部分):

WARNING: ThreadSanitizer: data race (pid=21774)                                                                                               

  Write of size 8 at 0x7d080000bfc8 by thread T1:                                                                                             
    #0 <null> <null>:0 (libtsan.so.0+0x00000001e2c0)                                                                                          
    #1 deallocate /usr/include/c++/4.8/ext/new_allocator.h:110 (exe+0x000000002a79)                                                           
    #2 deallocate /usr/include/c++/4.8/bits/alloc_Traits.h:377 (exe+0x000000002962)                                                           
    #3 _M_destroy /usr/include/c++/4.8/bits/shared_ptr_base.h:417 (exe+0x00000000306b)                                                        
    #4 <null> <null>:0 (libstdc++.so.6+0x0000000b5f8a)                                                                                        

  PrevIoUs atomic write of size 4 at 0x7d080000bfc8 by main thread:
    #0 <null> <null>:0 (libtsan.so.0+0x00000000da45)
    #1 __exchange_and_add /usr/include/c++/4.8/ext/atomicity.h:49 (exe+0x000000001c9f)
    #2 __exchange_and_add_dispatch /usr/include/c++/4.8/ext/atomicity.h:82 (exe+0x000000001d56)
    #3 std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() /usr/include/c++/4.8/bits/shared_ptr_base.h:141 (exe+0x00000000390d)
    #4 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() /usr/include/c++/4.8/bits/shared_ptr_base.h:553 (exe+0x00000000363C)
    #5 std::__shared_ptr<std::thread::_Impl_base,(__gnu_cxx::_Lock_policy)2>::~__shared_ptr() /usr/include/c++/4.8/bits/shared_ptr_base.h:810
 (exe+0x00000000351b)
    #6 std::shared_ptr<std::thread::_Impl_base>::~shared_ptr() /usr/include/c++/4.8/bits/shared_ptr.h:93 (exe+0x000000003547)
    #7 thread<main()::__lambda0> /usr/include/c++/4.8/thread:135 (exe+0x0000000020c3)
    #8 main /home/......./race-stl11b.cc:22 (exe+0x000000001e38)

感谢您的任何反馈,
乔斯

@H_696_2@

解决方法

看起来ThreadSanitizer在std :: thread实现上给你一个误报.

减少您的示例以不执行任何设置操作,如下所示:

#include <iostream>
#include <thread>
#include <set>

int main()
{
    std::set<int> bucket;
    std::thread t([&](){ /*bucket.insert(5);*/ });
    t.join();

    return 0;
}

仍然在ThreadSanitizer中给出相同的错误.

请注意,ThreadSanitizer找不到您的读写竞争条件.

@H_696_2@ @H_696_2@
@H_696_2@
@H_696_2@

大佬总结

以上是大佬教程为你收集整理的c – 来自std :: set insert()和find()的写入数据竞争?全部内容,希望文章能够帮你解决c – 来自std :: set insert()和find()的写入数据竞争?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。