【发布时间】:2021-02-08 08:55:07
【问题描述】:
根据shared_ptr/atomic,我们知道shared_ptr::reset() 是线程安全的。
防止被其他线程访问的对象被释放。我创建了一个store ptr 来保留过期的对象。
那么,以下代码在任何时候都是线程安全的?
class data_info
{
shared_ptr<sample> using;
shared_ptr<sample> store;
}
// function1 and function2 are used in different threads;
void function1(data_info &a)
{
a.using->do_something();
}
void function2(data_info &a)
{
a.store = a.using;
a.using.reset(new sample());
}
我写了一个演示来确认我的想法
#include <bits/stdc++.h>
#include <iostream>
#include <utility>
#include <thread>
#include <chrono>
#include <functional>
#include <atomic>
using namespace std;
#define ATOMIC_READLOCK(stored_data_ptr) \
{ \
auto atomic_readlock_##name = stored_data_ptr;
#define ATOMIC_READLOCK_RELEASE() \
}
#define ATOMIC_WRITELOCK(stored_data_ptr, new_data_ptr) \
stored_data_ptr = new_data_ptr
class bar
{
public:
bar() : num(1) {}
explicit bar(int x) : num(x) {}
int get_num()
{
return num;
}
void set_num(int x)
{
num = x;
}
private:
int num;
};
vector<int> v;
shared_ptr<bar> ptr_1, ptr_2;
void get_func()
{
for (int i = 0; i < 100000; i++)
{
ATOMIC_READLOCK(ptr_1);
v.push_back(ptr_1->get_num());
ATOMIC_READLOCK_RELEASE();
}
}
void set_func()
{
for (int i = 0; i < 100000; i++)
{
ptr_2 = make_shared<bar>(i);
ATOMIC_WRITELOCK(ptr_1, ptr_2);
}
}
int main()
{
std::thread t1(get_func);
std::thread t2(set_func);
t1.join();
t2.join();
}
但它会发生核心转储
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./reset'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x0000555a2a075c58 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() ()
[Current thread is 1 (Thread 0x7f70244ec700 (LWP 30265))]
(gdb) where
#0 0x0000555a2a075c58 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() ()
#1 0x0000555a2a0758b9 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() ()
#2 0x0000555a2a075790 in std::__shared_ptr<bar, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() ()
#3 0x0000555a2a0757c2 in std::shared_ptr<bar>::~shared_ptr() ()
#4 0x0000555a2a0753cc in get_func() ()
#5 0x0000555a2a076069 in void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void (*&&)()) ()
#6 0x0000555a2a075b3e in std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void (*&&)()) ()
#7 0x0000555a2a077b52 in decltype (__invoke((_S_declval<0ul>)())) std::thread::_Invoker<std::tuple<void (*)()> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) ()
#8 0x0000555a2a077af0 in std::thread::_Invoker<std::tuple<void (*)()> >::operator()() ()
#9 0x0000555a2a077a3c in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> > >::_M_run() ()
#10 0x00007f70251706df in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#11 0x00007f7024c836db in start_thread (arg=0x7f70244ec700) at pthread_create.c:463
#12 0x00007f70249aca3f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
【问题讨论】:
标签: c++ multithreading locking shared-ptr atomic