Masao Liu Masao Liu - 9 days ago 5
C++ Question

Make a safe Reader/Writer vector

Inspired by this code, I am trying to implement a Reader/Writer

vector
that can safely call
push_back()
concurrently by threads.

Once this class is in place, I might then create method
erase()
by calling
std::swap()
, which swaps the target item and the last item and then erase the last item in the collection. In this way, I assume that the performance should be fair because deleting an item in the middle of collection does not invoke moving all items following the target item in the collection.

Unfortunately, the following code:

#include <vector>
#include <boost/thread/shared_mutex.hpp> //shared_mutex
#include <memory> //shared_ptr
#include <utility> //swap()

template <class T>
class readers_writer_vector
{
std::shared_ptr<boost::shared_mutex> pm;
std::vector<T> data;
public:
readers_writer_vector() :
pm(new std::shared_ptr<boost::shared_mutex>){}
void push_back(const T& item){
boost::unique_lock<boost::shared_mutex> lock(*pm); //wrong design
data.push_back(item);
}
};

int main()
{
readers_writer_vector<int> db;
db.push_back(1);
return 0;
}


yields the following compilation errors:

/usr/include/c++/4.9/bits/shared_ptr_base.h:871:39: error: cannot convert ‘std::shared_ptr<boost::shared_mutex>*’ to ‘boost::shared_mutex*’ in initialization
: _M_ptr(__p), _M_refcount(__p)

// g++ -std=c++11 -Iboost -lboost t.cpp


How do I fix it? Please!

Answer

Because pm is std::shared_ptr<boost::shared_mutex> not std::shared_ptr<boost::shared_mutex>*. You can use this:

readers_writer_vector() :
    pm(std::make_shared<boost::shared_mutex>()){}

Anyway, why do you need pointer/smart pointer? This is better fit:

template <class T>
class readers_writer_vector
{
    boost::shared_mutex pm;
    std::vector<T> data;
public:
    void push_back(const T& item){
        boost::unique_lock<boost::shared_mutex> lock(pm);
        data.push_back(item);
    }
};