gpt4 book ai didi

c++ - 并发对象池提供 boost::shared_ptr

转载 作者:行者123 更新时间:2023-11-30 04:33:52 25 4
gpt4 key购买 nike

我想实现一个并发对象池,其中返回一个 shared_ptr 并且不需要显式地将它返回到池中。我基本上在并发队列中为其分配了一个推送的 shared_ptr 数组,并实现了一个自定义删除器。似乎工作。我错过了什么吗?

#ifndef CONCURRENTOBJECTPOOL_H
#define CONCURRENTOBJECTPOOL_H

#include <boost/shared_ptr.hpp>
#include <boost/shared_array.hpp>
#include <tbb/concurrent_queue.h>

namespace COP
{

template<typename T>
class ConcurrentObjectPool;

namespace
{
template<typename T>
class ConcurrentObjectPoolDeletor
{
public:
ConcurrentObjectPoolDeletor(ConcurrentObjectPool<T>& aConcurrentObjectPool):
_concurrentObjectPool(aConcurrentObjectPool) {}

void operator()(T *p) const;

private:
ConcurrentObjectPool<T>& _concurrentObjectPool;
};
} // Anonymous namespace for ConcurrentObjectPoolDeletor

template <typename T>
class ConcurrentObjectPool
{
public:
ConcurrentObjectPool(const unsigned int aPoolSize)
: _goingDown(false),
_poolSize(aPoolSize),
_pool(new T[_poolSize]),
_ConcurrentObjectPoolDeletor(*this)
{
for(unsigned int i = 0; i < _poolSize; ++i)
{
boost::shared_ptr<T> curr(&_pool[i], _ConcurrentObjectPoolDeletor);
_objectQueue.push(curr);
}
}

boost::shared_ptr<T> loan()
{
boost::shared_ptr<T> curr;
_objectQueue.pop(curr);
return curr;
}

~ConcurrentObjectPool()
{
_goingDown = true;
_objectQueue.clear();
}

private:
void payBack(T * p)
{
if (! _goingDown)
{
boost::shared_ptr<T> curr(p, _ConcurrentObjectPoolDeletor);
_objectQueue.push(curr);
}
}

bool _goingDown;
const unsigned int _poolSize;
const boost::shared_array<T> _pool;
const ConcurrentObjectPoolDeletor<T> _ConcurrentObjectPoolDeletor;
tbb::concurrent_bounded_queue<boost::shared_ptr<T> > _objectQueue;
friend class ConcurrentObjectPoolDeletor<T>;
};

namespace
{
template<typename T>
void ConcurrentObjectPoolDeletor<T>::operator()(T *p) const
{
_concurrentObjectPool.payBack(p);
}
} // Anonymous namespace for ConcurrentObjectPoolDeletor

} // Namespace COP

#endif // CONCURRENTOBJECTPOOL_H

最佳答案

ConcurrentObjectPool 的析构函数中设置 _goingDown 标志和在 payBack() 中读取标志之间存在竞争。它可能导致内存泄漏。

实际上,如果您不尝试使析构函数安全地与 payBack() 同时运行,也许会更好。无论如何它都不安全,因为 _goingDown 标志是池对象的一部分,因此在池被销毁后访问它会导致未定义的行为 - 即所有对象都必须返回到池中在它被摧毁之前。

关于c++ - 并发对象池提供 boost::shared_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6340553/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com