Pet*_*iak 16 c++ multithreading thread-safety c++11 clang++
在使用clang的线程消毒剂时,我们注意到了数据竞争警告.我们认为这是由于std :: string的copy-on-write技术不是线程安全的,但我们可能是错的.我们减少了对此代码的警告:
void test3() {
std::unique_ptr<std::thread> thread;
{
auto output = make_shared<string>();
std::string str = "test";
thread.reset(new std::thread([str, output]() { *output += str; }));
// The str string now goes out of scope but due to COW
// the captured string may not have the copy of the content yet.
}
thread->join();
}
Run Code Online (Sandbox Code Playgroud)
在使用线程清理程序编译时:
clang++ -stdlib=libc++ -std=c++11 -O0 -g -fsanitize=thread -lpthread -o test main.cpp
Run Code Online (Sandbox Code Playgroud)
要么
clang++ -std=c++11 -O0 -g -fsanitize=thread -lpthread -o test main.cpp
Run Code Online (Sandbox Code Playgroud)
并且当多次运行时,它最终会产生此警告:
WARNING: ThreadSanitizer: data race (pid=30829)
Write of size 8 at 0x7d0c0000bef8 by thread T62:
#0 operator delete(void*) <null>:0
...
Previous write of size 1 at 0x7d0c0000befd by thread T5:
#0 std::__1::char_traits<char>::assign(char&, char const&) string:639
...
Run Code Online (Sandbox Code Playgroud)
这是线程消毒器的假阳性还是真正的数据竞争?如果是后者,它可以在不更改代码的情况下工作(例如通过将一些标志传递给编译器),这是字符串实现中的已知错误(或其他内容)吗?
更新:clang --version输出:
Ubuntu clang version 3.5-1ubuntu1 (trunk) (based on LLVM 3.5)
Target: x86_64-pc-linux-gnu
Thread model: posix
Run Code Online (Sandbox Code Playgroud)
更新:我用来重现此警告的cpp.
[编辑] 下面的假设被证明是错误的,请参阅评论中的链接。上面代码中生成的线程是 T5,而不是 T62。
了解线程 ID 很有用,但我假设 T5 是主线程,T62 是衍生线程。看起来副本是在主线程上创建的(在新线程生成之前)并在新线程上销毁(显然)。这是安全的,因为新线程在主线程存在之前无法与主线程竞争。
因此,这是一个线程清理程序错误。它无法检查线程 T62 在上次写入时是否存在。
| 归档时间: |
|
| 查看次数: |
1011 次 |
| 最近记录: |