C++ version of CopyOnWriteArrayList
Java has CopyOnWriteArrayList, which enables me to iterate and mutat开发者_如何学JAVAe using 2 different threads simultaneously, without having any external locking.
Do we have any similar thread safety data structure for C++?
There's nothing in the standard library which would support this. Given the interface to C++ standard containers, I'm not sure it's possible. You'd have to start with something like:
template <typename T>
class CopyOnWriteVector
{
boost::shared_ptr<std::vector<T> > myData;
void uniqueCopy()
{
myData = boost::shared_ptr<std::vector<T> >( new std::vector<T>( *myData ) );
}
public:
// ...
// for example...
void push_back( T const& newElement )
{
uniqueCopy();
myData->push_back( newElement );
}
// Similar for all other non-const functions.
// const functions just forward, without the call to
uniqueCopy.
};
This doesn't work, however, for functions which return handles to some
internal data: either iterators or references to elements. For
iterators, it would be possible to create an iterator which contains
a shared_ptr
to the container it iterates into, e.g.:
template <typename T>
class CopyOnWriteVector
{
// ...
public:
class iterator : public std::random_access_iterator_tag
{
boost::shared_ptr<std::vector<T> > myVector;
typename std::vector<T>::iterator myImpl;
public:
iterator() {} // for convenience...
iterator( boost::shared_ptr<std::vector<T> > const& vector,
typename std::vector<T>::iterator initialValue )
: myVector( vector )
, myImpl( initialValue )
{
}
// All other iterator functions forward directly to myImpl
};
};
The functions which return references are another issue; you can't replace the reference with a smart reference, or a proxy of any type.
(Note: all of the above code is just off the top of my head, and probably contains significant errors. It's just to give an idea of the direction you might take.)
精彩评论