尝试编写自定义Allocate_Shared分配器并将其变为thread_local时崩溃
Crash when try to write a custom allocate_shared allocator and make it thread_local
我的程序使用make_shared在每个线程中非常频繁地创建和破坏几种类型的小对象,并且共享_ptr不会传递给另一个线程,在这种情况下,我决定去用boost :: pool编写自定义Allocate_Shared分配器作为其成员,以根据类型分配固定的内存大小。
我的代码如下:
quadallocator.h:
#include <boost/pool/pool.hpp>
template<typename T>
class ObjectAllocator
{
public:
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
auto static constexpr block_size=64+sizeof(value_type);
public:
ObjectAllocator() noexcept:pool_(block_size){}
ObjectAllocator(const ObjectAllocator &other) noexcept :pool_(block_size){}
~ObjectAllocator()=default;
template<typename U>
ObjectAllocator(const ObjectAllocator<U> &other) noexcept :pool_(block_size){}
template<typename U>
ObjectAllocator& operator= (const ObjectAllocator<U> &other){
return *this;
}
ObjectAllocator<T>& operator = (const ObjectAllocator &other){
return *this;
}
template<typename U>
struct rebind{ typedef ObjectAllocator<U> other; };
T *allocate(size_type n, const void *hint=nullptr){
#ifdef _DEBUG
assert(n==1);
#endif
return static_cast<T*>(pool_.malloc());
}
void deallocate(T *ptr, size_type n){
#ifdef _DEBUG
assert(n==1);
#endif
pool_.free(ptr);
}
private:
boost::pool<> ObjectAllocator<T>::pool_(block_size);
}
template<typename T, typename U>
inline bool operator == (const ObjectAllocator<T>&, const ObjectAllocator<U>&){
return true;
}
template<typename T, typename U>
inline bool operator != (const ObjectAllocator<T>& a, const ObjectAllocator<U> &b){
return !(a==b);
}
namespace Allocator {
template <typename T>
thread_local ObjectAllocator<T> allocator;
}
main.cpp:
class ObjectA{
public:
int s=0;
void func(){
std::cout<<s<<std::endl;
}
ObjectA() {//std::cout<<"()"<<std::endl;}
~ObjectA() {//std::cout<<"~"<<std::endl;}
};
std::vector<std::shared_ptr<ObjectA>> vec;
void test(){
static uint32_t loop_count=1000*1000;
for(uint32_t i=0;i<loop_count;i++){
shared_ptr<ObjectA> packet = allocate_shared<ObjectA, ObjectAllocator<ObjectA>>(Allocator::allocator<ObjectA>);
vec.push_back(packet);
}
vec.clear();
}
std::vector<std::shared_ptr<ObjectA>> vec2;
void test2(){
static uint32_t loop_count=1000*1000;
for(uint32_t i=0;i<loop_count;i++){
shared_ptr<ObjectA> packet = allocate_shared<ObjectA, ObjectAllocator<ObjectA>>(Allocator::allocator<ObjectA>);
vec2.push_back(packet);
}
vec2.clear();
}
int main() {
std::thread thread1(test);
test2();
return 0;
}
当我尝试测试它时,它会崩溃,我不知道为什么。谁能帮助使它正确?预先感谢。
调试器在shared_ptr_base.h
中说seg故障void* _m_get_deleter(const std :: type_info&amp; __ti)const noexcept {return _m_pi?_m_pi-> _ m_get_deleter(__ ti):nullptr;}
当我尝试使boost :: poost静态时,它在单线程中正常工作,并且在多线程中崩溃调试器说shone_ptr_base.h
中的seg故障:_M_USE_COUNT(1),_M_WEAK_COUNT(1){}
更新:我将BOOST :: pool是静态thread_local,并且现在正常工作
template<typename T>
class ObjectAllocator
{
public:
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
auto static constexpr block_size=64+sizeof(value_type);
public:
ObjectAllocator() noexcept{}
ObjectAllocator(const ObjectAllocator &other) noexcept {}
~ObjectAllocator()=default;
template<typename U>
ObjectAllocator(const ObjectAllocator<U> &other) noexcept {}
template<typename U>
ObjectAllocator& operator= (const ObjectAllocator<U> &other){
return *this;
}
ObjectAllocator<T>& operator = (const ObjectAllocator &other){
return *this;
}
template<typename U>
struct rebind{ typedef ObjectAllocator<U> other; };
T *allocate(size_type n, const void *hint=nullptr){
#ifdef _DEBUG
assert(n==1);
#endif
return static_cast<T*>(pool_.malloc());
}
void deallocate(T *ptr, size_type n){
#ifdef _DEBUG
assert(n==1);
#endif
pool_.free(ptr);
}
private:
thread_local static boost::pool<> pool_;
};
template<typename T>
thread_local boost::pool<> ObjectAllocator<T>::pool_(block_size);
template<typename T, typename U>
inline bool operator == (const ObjectAllocator<T>&, const ObjectAllocator<U>&){
return true;
}
template<typename T, typename U>
inline bool operator != (const ObjectAllocator<T>& a, const ObjectAllocator<U> &b){
return !(a==b);
}
namespace Allocator {
template <typename T>
thread_local static ObjectAllocator<T> allocator;
}
template <typename T, typename ...Args>
inline auto custom_make_shared(Args... args){
return std::allocate_shared<T,ObjectAllocator<T>>(Allocator::allocator<T>,std::forward<Args>(args)...);
}
每次称为boost::pool
的ObjectAllocator
的复制构造函数。
当std::allocate_shared
复制分配器(cppReference)时,用于分配std::shared_ptr
的ObjectAllocator
的实例在shared_ptr
被销毁之前会被其池破坏。
相关的问题:C 状态分配者DE-CORPATE问题
可能与您的问题无关,但是还有其他问题:
- 您不加入
main
中的thread1
。这将调用std::terminate
并崩溃您的程序。 -
boost::pool<> ObjectAllocator<T>::pool_(block_size);
-ObjectAllocator<T>::
零件是多余的,非标准的。(AFAIK仅在MSVC中接受)
相关文章:
- 当回溯以零开始时,如何调试崩溃
- 内联映射初始化的动态atexit析构函数崩溃
- 执行函数时导致崩溃的变量
- 程序崩溃并显示"std::out_of_range"错误
- CoInitialize()在单独的线程上崩溃而不返回
- 使用调试/崩溃报告将应用程序部署到客户端
- 在std::thread中,joinable()然后join()线程安全吗
- 为什么所有C++编译器都会崩溃或挂起此代码
- 为什么lambda在clang上崩溃而不是在gcc上崩溃
- 为什么我的多线程作业队列崩溃
- ExtractIconEx:可以工作,但偶尔会崩溃
- 为什么引用传递会导致此崩溃(C++)
- 试图创建流或fopen时程序崩溃
- 类对象数组的问题会导致崩溃
- 排序时无法执行交换操作.我做的时候它会崩溃.为什么
- ZeroMQ 在使用 std::thread 创建工作线程时崩溃
- 为什么 std::make_unique<std::thread>(somefun()) 会在我没有调用 release() 时生成崩溃,并且在调用时会生成崩溃?
- std::thread::d etach 在原始调用者被销毁后会导致崩溃
- 为什么主线程在此C++示例代码段中使用<thread>崩溃?
- 为什么这个简单的线程c++程序在退出时崩溃,除非我调用thread.join()