如何进行线程安全shared_ptr修改和访问?
How to do thread safe shared_ptr modification and access?
目标:我想修改内部信息,并尽可能快地从多个线程同步访问此信息
我简化了下面的代码,但这就是我试图实现这一点的方式。
我有 2 个共享指针。
一个叫m_mutable_data
,另一个叫m_const_data
。
m_mutable_data
以链保护方式更新。m_const_data
每60年代也以链保护的方式更新m_mutable_data内容。
这是使用新数据重置共享指针m_const_data
唯一位置。m_const_data
由许多线程同步读取,每秒 1000+ 次。
法典
class black_list_container : public std::enable_shared_from_this<black_list_container>
{
struct meta_data
{
bool blacked;
}
struct black_list_data
{
std::unordered_map<uint32_t,meta_data> data;
}
public:
#pragma optimize( "", off )
bool is_blacked(uint32_t id)
{
// This call is called from many different threads (1000+ calls per second)
// should be synchronous and as fast as possible
auto c = m_const_data;
return c->data[id].blacked;
}
#pragma optimize( "", on )
#pragma optimize( "", off )
void update_const_data()
{
// Called internaly by timer every 60s to update m_const_data with contents of m_mutable_data
// Guarded with strand
m_strand->post([self{shared_from_this()}]{
auto snapshot = new black_list_data();
snapshot->data = m_mutable_data->data;
m_const_data.reset(snapshot);
});
}
#pragma optimize( "", on )
private:
void internal_modification_mutable_data()
{
// Called internaly by different metrics
// Guarded with strand
m_strand->post([self{shared_from_this()}]{
// .... do some modification on internal m_mutable_data
});
}
boost::asio::io_context::strand m_strand;
std::shared_ptr<black_list_data> m_mutable_data;
std::shared_ptr<black_list_data> m_const_data;
};
非常非常很少此代码在线在方法"is_blacked"中崩溃
auto c = m_const_data;
这是回溯
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Core was generated by `./STRATUM-01'.
Program terminated with signal 6, Aborted.
#0 0x00007fe09aaf1387 in raise () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.17-307.el7.1.x86_64 libgcc-4.8.5-39.el7.x86_64 libstdc++-4.8.5-39.el7.x86_64
(gdb) bt
#0 0x00007fe09aaf1387 in raise () from /lib64/libc.so.6
#1 0x00007fe09aaf2a78 in abort () from /lib64/libc.so.6
#2 0x00007fe09ab33ed7 in __libc_message () from /lib64/libc.so.6
#3 0x00007fe09ab3c299 in _int_free () from /lib64/libc.so.6
#4 0x00000000005fae36 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x7fe0440aeaa0) at /opt/rh/devtoolset-7/root/usr/include/c++/7/bits/shared_ptr_base.h:154
#5 0x00000000006b9205 in ~__shared_count (this=<synthetic pointer>, __in_chrg=<optimized out>) at /opt/rh/devtoolset-7/root/usr/include/c++/7/bits/shared_ptr_base.h:684
#6 ~__shared_ptr (this=<synthetic pointer>, __in_chrg=<optimized out>) at /opt/rh/devtoolset-7/root/usr/include/c++/7/bits/shared_ptr_base.h:1123
#7 ~shared_ptr (this=<synthetic pointer>, __in_chrg=<optimized out>) at /opt/rh/devtoolset-7/root/usr/include/c++/7/bits/shared_ptr.h:93
#8 black_list_container_impl::is_blacked (this=0x7fe08c287e50, id=23654) at /var/lib/jenkins/workspace/validator/src/black_list_container.cpp:69
我不确定为什么在帧 #7 中调用shared_ptr的破坏
显然我没有实现我的目标,所以请引导我进入以线程安全的方式实际实现我的目标的模式。
我知道我本可以使用
std::atomic<std::shared_ptr<black_list_data>> m_const_data;
但是,这不会影响从许多不同线程读取时的性能吗?
我想我在这篇文章中找到了问题的答案 原子智能指针.
所以我必须将代码更改为update_const_data()
auto snapshot = std::make_shared<black_list_data>();
snapshot->data = m_mutable_data->data;
std::atomic_store(&m_const_data, snapshot);
和代码is_blacked()
auto c = std::atomic_load(&m_const_data);
相关文章:
- 回旋/修改阵列访问
- 如何进行线程安全shared_ptr修改和访问?
- C++:成员不可访问-使用友元函数允许一个类修改另一个类的成员数据
- 尝试修改数组时出现写访问冲突
- 如何在python脚本中使用Pybind11修改/访问C++指针
- 避免使用大量全局变量或使其易于访问和修改的最佳方法
- 是二维阵列访问/修改时间组
- 数组在函数中作为参数传递并被访问,那么为什么从函数返回后数组的值会被修改呢?
- 是否可以安全地(读取)从BITSET(C )进行一些访问,该咬合可能会通过其他线程修改
- 作用域问题:如何从类外查看(不访问也不修改!)私有属性
- 如何在不违反封装的情况下合法访问和修改私有字段矢量和映射
- 访问/修改Qt/QML中某个类型的所有实例
- 使用基对象修改/访问派生类的信息的有问题的设计
- 重新配置C++代码以处理“警告:未按顺序修改和访问参数”
- 从子 DLL 访问/修改变量
- C++ 如何使用 [] 访问和修改数组
- 如何在进程已经在访问数据结构时修改数据结构
- 视觉获取链接错误:C++中的外部.如何访问在文件 A 中修改的变量的值.CPP在另一个文件 B .CPP中修改
- 访问全局变量以修改值
- C++:未排序的修改和对"i"的访问