奇怪的共享行为 我发现了一个非常奇怪的行为,在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>(&current->next);
            newNode->next = next;
        } while (!std::atomic_compare_exchange_weak<Node>(&current->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