源代码如下:
#include <iostream>
#include <string>
#include <vector>
#include <thread>
struct A {
std::string name = "blacksmith";
int age = 100;
};
struct B1 {
std::string local_name = "jd-B1";
void func1(A* a) {
while (true) {
a->name = local_name;
std::string key = local_name + "**";
}
}
};
struct B2 {
std::string local_name = "jd-B2";
void func1(A* a) {
while (true) {
a->name = local_name;
std::string key = local_name + "**";
}
}
};
int main() {
/**
* 探测是否支持 COW
*/
std::string* test = new std::string("blacksmith");
std::string name = *test;
std::cout << "test:" << test->data() << ", name=" << name.data() << std::endl;
if (test->data() == name.data()) {
std::cout << "COW(Copy On Write) support!" << std::endl;
} else {
std::cout << "COW(Copy On Write) NOT support!" << std::endl;
}
delete test;
/**
* 多线程操作
*/
std::vector<std::thread> th_vec;
int thread_count = 4;
A a;
B1 b1;
B2 b2;
for (int i = 0; i < thread_count; i++) {
th_vec.emplace_back([&](){
b1.func1(&a);
});
th_vec.emplace_back([&](){
b2.func1(&a);
});
}
for (auto& item : th_vec) {
item.join();
}
std::cout << "=========END==========" << std::endl;
return 0;
}
编译:
g++ --std=c++11 string-test.cc -g -lpthread
查看 coredump 栈:
(gdb) bt
#0 0x00007f5613350e20 in __memcpy_ssse3 () from /usr/lib64/libc.so.6
#1 0x00007f5613ba8650 in std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) () from /usr/lib64/libstdc++.so.6
#2 0x00007f5613ba86d4 in std::string::reserve(unsigned long) () from /usr/lib64/libstdc++.so.6
#3 0x00007f5613ba893f in std::string::append(char const*, unsigned long) () from /usr/lib64/libstdc++.so.6
#4 0x0000000000402808 in std::operator+<char, std::char_traits<char>, std::allocator<char> > (
__lhs="jd-B2", '\000' <repeats 11 times>, "!\000\000\000\000\000\000\000@9@\000\000\000\000\000(I\213\071\375\177\000\000\060I\213\071\375\177\000\000Q\002\000\000\000\000\000\000\"", '\000' <repeats 15 times>, "\001", '\000' <repeats 15 times>, "\377\377\377\377\377\377\377\377\000\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377", '\000' <repeats 88 times>..., __rhs=0x40386a "**")
at /opt/rh/devtoolset-7/root/usr/include/c++/7/bits/basic_string.h:5917
#5 0x000000000040263f in B2::func1 (this=0x7ffd398b4920, a=0x7ffd398b4930) at string-test.cc:28
#6 0x0000000000401108 in <lambda()>::operator()(void) const (__closure=0x19a5368) at string-test.cc:62
#7 0x0000000000401fde in std::__invoke_impl<void, main()::<lambda()> >(std::__invoke_other, <lambda()> &&) (__f=...) at /opt/rh/devtoolset-7/root/usr/include/c++/7/bits/invoke.h:60
#8 0x0000000000401cb0 in std::__invoke<main()::<lambda()> >(<lambda()> &&) (__fn=...) at /opt/rh/devtoolset-7/root/usr/include/c++/7/bits/invoke.h:95
#9 0x0000000000402392 in std::thread::_Invoker<std::tuple<main()::<lambda()> > >::_M_invoke<0>(std::_Index_tuple<0>) (this=0x19a5368) at /opt/rh/devtoolset-7/root/usr/include/c++/7/thread:234
#10 0x000000000040233f in std::thread::_Invoker<std::tuple<main()::<lambda()> > >::operator()(void) (this=0x19a5368) at /opt/rh/devtoolset-7/root/usr/include/c++/7/thread:243
#11 0x00000000004022fe in std::thread::_State_impl<std::thread::_Invoker<std::tuple<main()::<lambda()> > > >::_M_run(void) (this=0x19a5360) at /opt/rh/devtoolset-7/root/usr/include/c++/7/thread:186
#12 0x000000000040343f in execute_native_thread_routine ()
#13 0x00007f5613df8dd5 in start_thread () from /usr/lib64/libpthread.so.0
#14 0x00007f5613302ead in clone () from /usr/lib64/libc.so.6
比较疑惑的一点是,多线程写 string,为什么不是在写入那一行 core,而是在后面拼接成员变量?
a->name = local_name; // 我理解应该是这一行报 core
std::string key = local_name + "**"; // 实际在操作 local_name 的时候 core,并且看栈,local_name 内存乱了
辛苦各位大佬,有时间的帮忙看看,很是疑惑。 谢谢。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.