2011-06-14 2 views
1

shared_ptr에서 반환되는 동시 객체 풀을 구현하고이를 명시 적으로 풀로 반환하는 것이 필요하지 않았습니다. 나는 기본적으로 배열을 shared_ptrs를 동시 대기열에 넣고 할당하고 사용자 정의 삭제자를 구현했습니다. 일하는 것 같습니다. 내가 놓친 게 있니?boost :: 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 
+0

이것은 http://codereview.stackexchange.com/에 속합니다. –

+0

헤더의 익명 네임 스페이스가 나에게 나쁜 생각 인 것 같습니다. ODR 위반에 대한 빠른 방법. –

+0

[Boost.Flyweight] (http://www.boost.org/doc/libs/release/libs/flyweight/doc/index.html)가 이미 문제를 해결합니까? – ildjarn

답변

2

ConcurrentObjectPool의 소멸자에 _goingDown 플래그를 설정하고 payBack()에 플래그를 읽는 것 사이에 경쟁이 있습니다. 메모리 누수가 발생할 수 있습니다.

사실, 소멸자가 payBack()과 동시에 실행되도록 안전하게하려고하지 않는 것이 더 좋을 수도 있습니다. 어쨌든 _goingDown 플래그가 풀 객체의 일부이므로 풀이 소멸 된 후에 액세스하는 것은 정의되지 않은 동작을 야기합니다. 즉, 모든 객체가 파괴되기 전에 풀로 반환되어야합니다.

0

좋아요. 그것을 사용하는 데 문제가 있습니까?

+1

확신 할 필요가 있습니다. 나는 항상 동시성에 뒤죽박죽이다. – Nikhil

관련 문제