奇怪的共享行为 我发现了一个非常奇怪的行为,在C++中使用了 STD::SyrdYPPTR 。 下面的示例非常适用于标准指针
但是,使用奇怪的共享行为 我发现了一个非常奇怪的行为,在C++中使用了 STD::SyrdYPPTR 。 下面的示例非常适用于标准指针,c++,c++11,shared-ptr,atomic,lock-free,C++,C++11,Shared Ptr,Atomic,Lock Free,但是,使用std::shared_ptr会导致分段错误。(见下面的回溯) 我知道,从多个线程访问std::shared_ptr是不安全的,因此我使用原子操作。即使是经典的锁也不能解决这个问题 Im使用gcc版本6.3.0 20170406(Ubuntu 6.3.0-12ubuntu2)和-Wall-O2-g和-std=c++17 有人知道解决方案或者代码崩溃的原因吗 #include <iostream> #include <thread> #include <ve
std::shared_ptr
会导致分段错误。(见下面的回溯)
我知道,从多个线程访问std::shared_ptr是不安全的,因此我使用原子操作。即使是经典的锁也不能解决这个问题
Im使用gcc版本6.3.0 20170406(Ubuntu 6.3.0-12ubuntu2)和-Wall-O2-g
和-std=c++17
有人知道解决方案或者代码崩溃的原因吗
#include <iostream>
#include <thread>
#include <vector>
#include <mutex>
template <typename T>
class list {
private:
struct Node {
T value;
std::shared_ptr<Node> next;
Node() : next(nullptr) {}
};
std::shared_ptr<Node> head;
public:
// create dummy-nodes
explicit list() : head(std::make_shared<Node>()){
head->next = std::make_shared<Node>();
};
void push_front(T val) {
std::shared_ptr<Node> current;
std::shared_ptr<Node> next;
std::shared_ptr<Node> newNode = std::make_shared<Node>();
newNode->value = val;
do {
current = std::atomic_load<Node>(&head);
next = std::atomic_load<Node>(¤t->next);
newNode->next = next;
} while (!std::atomic_compare_exchange_weak<Node>(¤t->next, &next, newNode));
}
};
int main(int argc, char* argv[]) {
list<int> ll;
std::vector<std::thread> threads;
const int thread_count = 8;
const int local_count = 200000;
std::mutex m;
for (int i = 0; i < thread_count; i++) {
threads.push_back(std::thread([&ll, i, local_count, &m]() {
for (int j = local_count * i; j < local_count * (i + 1); j++) {
m.lock(); // optional for testing; doesnt solve the problem
ll.push_front(j);
m.unlock();
}
}));
}
for (auto& thrd : threads) {
thrd.join();
}
return 0;
}
#包括
#包括
#包括
#包括
模板
班级名单{
私人:
结构节点{
T值;
std::共享\u ptr next;
Node():next(nullptr){}
};
std::共享头;
公众:
//创建虚拟节点
显式列表():head(std::make_shared()){
head->next=std::使_共享();
};
前推空(T val){
std::共享的ptr电流;
std::共享\u ptr next;
std::shared_ptr newNode=std::make_shared();
newNode->value=val;
做{
电流=标准::原子负载(&head);
next=std::原子加载(¤t->next);
新建节点->下一步=下一步;
}而(!std::atomic_compare_exchange_弱(¤t->next,&next,newNode));
}
};
int main(int argc,char*argv[]){
列表ll;
向量线程;
const int thread_count=8;
const int local_count=200000;
std::互斥m;
对于(int i=0;i
gdb回溯:
0x0000555555555d4e in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x7fffd48eb0e0) at /usr/include/c++/6/bits/shared_ptr_base.h:150
150 _M_dispose();
(gdb) bt
#0 0x0000555555555d4e in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x7fffd48eb0e0) at /usr/include/c++/6/bits/shared_ptr_base.h:150
#1 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=<optimized out>, __in_chrg=<optimized out>) at /usr/include/c++/6/bits/shared_ptr_base.h:662
#2 std::__shared_ptr<list<int>::Node, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=<optimized out>, __in_chrg=<optimized out>) at /usr/include/c++/6/bits/shared_ptr_base.h:928
#3 std::shared_ptr<list<int>::Node>::~shared_ptr (this=<optimized out>, __in_chrg=<optimized out>) at /usr/include/c++/6/bits/shared_ptr.h:93
#4 list<int>::Node::~Node (this=<optimized out>, __in_chrg=<optimized out>) at src/main.cpp:11
#5 __gnu_cxx::new_allocator<list<int>::Node>::destroy<list<int>::Node> (this=<optimized out>, __p=<optimized out>) at /usr/include/c++/6/ext/new_allocator.h:124
#6 std::allocator_traits<std::allocator<list<int>::Node> >::destroy<list<int>::Node> (__a=..., __p=<optimized out>) at /usr/include/c++/6/bits/alloc_traits.h:487
#7 std::_Sp_counted_ptr_inplace<list<int>::Node, std::allocator<list<int>::Node>, (__gnu_cxx::_Lock_policy)2>::_M_dispose (this=<optimized out>) at /usr/include/c++/6/bits/shared_ptr_base.h:529
#8 0x0000555555555d51 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x7fffd48eb110) at /usr/include/c++/6/bits/shared_ptr_base.h:150
#9 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=<optimized out>, __in_chrg=<optimized out>) at /usr/include/c++/6/bits/shared_ptr_base.h:662
#10 std::__shared_ptr<list<int>::Node, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=<optimized out>, __in_chrg=<optimized out>) at /usr/include/c++/6/bits/shared_ptr_base.h:928
#11 std::shared_ptr<list<int>::Node>::~shared_ptr (this=<optimized out>, __in_chrg=<optimized out>) at /usr/include/c++/6/bits/shared_ptr.h:93
#12 list<int>::Node::~Node (this=<optimized out>, __in_chrg=<optimized out>) at src/main.cpp:11
#13 __gnu_cxx::new_allocator<list<int>::Node>::destroy<list<int>::Node> (this=<optimized out>, __p=<optimized out>) at /usr/include/c++/6/ext/new_allocator.h:124
#14 std::allocator_traits<std::allocator<list<int>::Node> >::destroy<list<int>::Node> (__a=..., __p=<optimized out>) at /usr/include/c++/6/bits/alloc_traits.h:487
#15 std::_Sp_counted_ptr_inplace<list<int>::Node, std::allocator<list<int>::Node>, (__gnu_cxx::_Lock_policy)2>::_M_dispose (this=<optimized out>) at /usr/include/c++/6/bits/shared_ptr_base.h:529
#16 0x0000555555555d51 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x7fffd48eb140) at /usr/include/c++/6/bits/shared_ptr_base.h:150
#17 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=<optimized out>, __in_chrg=<optimized out>) at /usr/include/c++/6/bits/shared_ptr_base.h:662
#18 std::__shared_ptr<list<int>::Node, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=<optimized out>, __in_chrg=<optimized out>) at /usr/include/c++/6/bits/shared_ptr_base.h:928
#19 std::shared_ptr<list<int>::Node>::~shared_ptr (this=<optimized out>, __in_chrg=<optimized out>) at /usr/include/c++/6/bits/shared_ptr.h:93
#20 list<int>::Node::~Node (this=<optimized out>, __in_chrg=<optimized out>) at src/main.cpp:11
#21 __gnu_cxx::new_allocator<list<int>::Node>::destroy<list<int>::Node> (this=<optimized out>, __p=<optimized out>) at /usr/include/c++/6/ext/new_allocator.h:124
#22 std::allocator_traits<std::allocator<list<int>::Node> >::destroy<list<int>::Node> (__a=..., __p=<optimized out>) at /usr/include/c++/6/bits/alloc_traits.h:487
#23 std::_Sp_counted_ptr_inplace<list<int>::Node, std::allocator<list<int>::Node>, (__gnu_cxx::_Lock_policy)2>::_M_dispose (this=<optimized out>) at /usr/include/c++/6/bits/shared_ptr_base.h:529
#24 0x0000555555555d51 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x7fffd48eb170) at /usr/include/c++/6/bits/shared_ptr_base.h:150
#25 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=<optimized out>, __in_chrg=<optimized out>) at /usr/include/c++/6/bits/shared_ptr_base.h:662
#26 std::__shared_ptr<list<int>::Node, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=<optimized out>, __in_chrg=<optimized out>) at /usr/include/c++/6/bits/shared_ptr_base.h:928
#27 std::shared_ptr<list<int>::Node>::~shared_ptr (this=<optimized out>, __in_chrg=<optimized out>) at /usr/include/c++/6/bits/shared_ptr.h:93
#28 list<int>::Node::~Node (this=<optimized out>, __in_chrg=<optimized out>) at src/main.cpp:11
#29 __gnu_cxx::new_allocator<list<int>::Node>::destroy<list<int>::Node> (this=<optimized out>, __p=<optimized out>) at /usr/include/c++/6/ext/new_allocator.h:124
#30 std::allocator_traits<std::allocator<list<int>::Node> >::destroy<list<int>::Node> (__a=..., __p=<optimized out>) at /usr/include/c++/6/bits/alloc_traits.h:487
#31 std::_Sp_counted_ptr_inplace<list<int>::Node, std::allocator<list<int>::Node>, (__gnu_cxx::_Lock_policy)2>::_M_dispose (this=<optimized out>) at /usr/include/c++/6/bits/shared_ptr_base.h:529
#32 0x0000555555555d51 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x7fffd48eb1a0) at /usr/include/c++/6/bits/shared_ptr_base.h:150
#33 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=<optimized out>, __in_chrg=<optimized out>) at /usr/include/c++/6/bits/shared_ptr_base.h:662
#34 std::__shared_ptr<list<int>::Node, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=<optimized out>, __in_chrg=<optimized out>) at /usr/include/c++/6/bits/shared_ptr_base.h:928
#35 std::shared_ptr<list<int>::Node>::~shared_ptr (this=<optimized out>, __in_chrg=<optimized out>) at /usr/include/c++/6/bits/shared_ptr.h:93
#36 list<int>::Node::~Node (this=<optimized out>, __in_chrg=<optimized out>) at src/main.cpp:11
#37 __gnu_cxx::new_allocator<list<int>::Node>::destroy<list<int>::Node> (this=<optimized out>, __p=<optimized out>) at /usr/include/c++/6/ext/new_allocator.h:124
#38 std::allocator_traits<std::allocator<list<int>::Node> >::destroy<list<int>::Node> (__a=..., __p=<optimized out>) at /usr/include/c++/6/bits/alloc_traits.h:487
#39 std::_Sp_counted_ptr_inplace<list<int>::Node, std::allocator<list<int>::Node>, (__gnu_cxx::_Lock_policy)2>::_M_dispose (this=<optimized out>) at /usr/include/c++/6/bits/shared_ptr_base.h:529
#40 0x0000555555555d51 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x7fffd48eb1d0) at /usr/include/c++/6/bits/shared_ptr_base.h:150
#41 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=<optimized out>, __in_chrg=<optimized out>) at /usr/include/c++/6/bits/shared_ptr_base.h:662
#42 std::__shared_ptr<list<int>::Node, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=<optimized out>, __in_chrg=<optimized out>) at /usr/include/c++/6/bits/shared_ptr_base.h:928
#43 std::shared_ptr<list<int>::Node>::~shared_ptr (this=<optimized out>, __in_chrg=<optimized out>) at /usr/include/c++/6/bits/shared_ptr.h:93
#44 list<int>::Node::~Node (this=<optimized out>, __in_chrg=<optimized out>) at src/main.cpp:11
#45 __gnu_cxx::new_allocator<list<int>::Node>::destroy<list<int>::Node> (this=<optimized out>, __p=<optimized out>) at /usr/include/c++/6/ext/new_allocator.h:124
#46 std::allocator_traits<std::allocator<list<int>::Node> >::destroy<list<int>::Node> (__a=..., __p=<optimized out>) at /usr/include/c++/6/bits/alloc_traits.h:487
#47 std::_Sp_counted_ptr_inplace<list<int>::Node, std::allocator<list<int>::Node>, (__gnu_cxx::_Lock_policy)2>::_M_dispose (this=<optimized out>) at /usr/include/c++/6/bits/shared_ptr_base.h:529
#48 0x0000555555555d51 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x7fffd48eb200) at /usr/include/c++/6/bits/shared_ptr_base.h:150
#49 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=<optimized out>, __in_chrg=<optimized out>) at /usr/include/c++/6/bits/shared_ptr_base.h:662
#50 std::__shared_ptr<list<int>::Node, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=<optimized out>, __in_chrg=<optimized out>) at /usr/include/c++/6/bits/shared_ptr_base.h:928
#51 std::shared_ptr<list<int>::Node>::~shared_ptr (this=<optimized out>, __in_chrg=<optimized out>) at /usr/include/c++/6/bits/shared_ptr.h:93
#52 list<int>::Node::~Node (this=<optimized out>, __in_chrg=<optimized out>) at src/main.cpp:11
#53 __gnu_cxx::new_allocator<list<int>::Node>::destroy<list<int>::Node> (this=<optimized out>, __p=<optimized out>) at /usr/include/c++/6/ext/new_allocator.h:124
#54 std::allocator_traits<std::allocator<list<int>::Node> >::destroy<list<int>::Node> (__a=..., __p=<optimized out>) at /usr/include/c++/6/bits/alloc_traits.h:487
#55 std::_Sp_counted_ptr_inplace<list<int>::Node, std::allocator<list<int>::Node>, (__gnu_cxx::_Lock_policy)2>::_M_dispose (this=<optimized out>) at /usr/include/c++/6/bits/shared_ptr_base.h:529
标准中的0x00005555D4E::_Sp_counted_base::_M_release(this=0x7fffd48eb0e0)位于/usr/include/c++/6/bits/shared_ptr_base.h:150
150_M_dispose();
(gdb)英国电信
#标准中的0 0x00005555D4E::_Sp_counted_base::_M_release(this=0x7fffd48eb0e0)位于/usr/include/c++/6/bits/shared_ptr_base.h:150
#1 std::uu shared_count::~u shared_count(this=,u in_chrg=)at/usr/include/c++/6/bits/shared_ptr_base.h:662
#2 std::uu shared_ptr::~u shared_ptr(this=,u in_chrg=)at/usr/include/c++/6/bits/shared_ptr_base.h:928
#3 std::shared_ptr::~shared_ptr(this=,u in_chrg=)at/usr/include/c++/6/bits/shared_ptr.h:93
#4 list::Node::~Node(this=,uu in_chrg=)位于src/main.cpp:11
#位于/usr/include/c++/6/ext/new_分配器的5_uugnu cxx::new_分配器::destroy(this=,u p=)h:124
#6 std::allocator_traits::destroy(u a=…,u p=)at/usr/include/c++/6/bits/alloc_traits.h:487
#7标准::_Sp_counted_ptr_in place::_M_dispose(this=)位于/usr/include/c++/6/bits/shared_ptr_base.h:529
#标准中的8 0x00005555D51::_Sp_counted_base::_M_release(this=0x7fffd48eb110)位于/usr/include/c++/6/bits/shared_ptr_base.h:150
#9 std::uu shared_count::~u shared_count(this=,u in_chrg=)at/usr/include/c++/6/bits/shared_ptr_base.h:662
#10 std::uu shared_ptr::~u shared_ptr(this=,u in_chrg=)at/usr/include/c++/6/bits/shared_ptr_base.h:928
#11 std::shared_ptr::~shared_ptr(this=,u in_chrg=)at/usr/include/c++/6/bits/shared_ptr.h:93
#12列表::节点::~Node(this=,__in_chrg=)位于src/main.cpp:11
#13在/usr/include/c++/6/ext/new_分配器处的new_分配器::destroy(this=,u p=)。h:124
#14 std::allocator_traits::destroy(u a=…,u p=)at/usr/include/c++/6/bits/alloc_traits.h:487
#15标准::_Sp_counted_ptr_in place::_M_dispose(this=)位于/usr/include/c++/6/bits/shared_ptr_base.h:529
#标准中的16 0x00005555D51::_Sp_counted_base::_M_release(this=0x7fffd48eb140)位于/usr/include/c++/6/bits/shared_ptr_base.h:150
#17 std::uu shared_count::~u shared_count(this=,u in_chrg=)at/usr/include/c++/6/bits/shared_ptr_base.h:662
#18 std::uu shared_ptr::~u shared_ptr(this=,u in_chrg=)at/usr/include/c++/6/bits/shared_ptr_base.h:928
#19 std::shared_ptr::~shared_ptr(this=,u in_chrg=)at/usr/include/c++/6/bits/shared_ptr.h:93
#20列表::节点::~Node(this=,uu in_chrg=)位于src/main.cpp:11
#在/usr/include/c++/6/ext/new_分配器处21_uu-gnu-cxx::new_分配器::destroy(this=,u-p=)。h:124
#22 std::allocator_traits::destroy(u a=…,u p=)at/usr/include/c++/6/bits/alloc_traits.h:487
#23标准::_Sp_counted_ptr_in place::_M_dispose(this=)位于/usr/include/c++/6/bits/shared_ptr_base.h:529
#标准中的24 0x00005555D51::_Sp_counted_base::_M_release(this=0x7fffd48eb170)位于/usr/include/c++/6/bits/shared_ptr_base.h:150
#25 std::uu shared_count::~u shared_count(this=,u in_chrg=)at/usr/include/c++/6/bits/shared_ptr_base.h:662
#26 std::uu shared_ptr::~u shared_ptr(this=,u in_chrg=)at/usr/include/c++/6/bits/shared_ptr_base.h:928
#27 std::shared_ptr::~shared_ptr(this=,u in_chrg=)at/usr/include/c++/6/bits/shared_ptr.h:93
#28列表::节点::~Node(this=,uu in_chrg=)位于src/main.cpp:11
#29在/usr/include/c++/6/ext/new_分配器处的new_分配器::destroy(this=,u p=)。h:124
#30 std::allocator_traits::destroy(u a=…,u p=)at/usr/include/c++/6/bits/alloc_traits.h:487
#31标准::_Sp_counted_ptr_in place::_M_dispose(this=)位于/usr/include/c++/6/bits/shared_ptr_base.h:529
#标准中的32 0x00005555D51::_Sp_counted_base::_M_release(this=0x7fffd48eb1a0)位于/usr/include/c++/6/bits/shared_ptr_base.h:150
#33 std::uu shared_count::~u shared_count(this=,u in_chrg=)at/usr/include/c++/6/bits/shared_ptr_base.h:662
#34 std::uu shared_ptr::~u shared_ptr(this=,u in_chrg=)at/usr/include/c++/6/bits/shared_ptr_base.h:928
#35 std::shared_ptr::~shared_ptr(this=,u in_chrg=)at/usr/include/c++/6/bits/shared_ptr.h:93
#36 list::Node::~Node(this=,uu in_chrg=)位于src/main.cpp:11
#37 uuugnucxx::新建分配器::销毁(this=,uup=)a