Reputation: 43447
I have a vector (a large buffer of strings) which I hope to read from a network thread while it is being written to by the main thread.
As vector
is not thread-safe, the typical approach would be to lock the access to it from both threads.
However my insight has been that this should be only strictly necessary when the particular write will resize the vector, which will cause the realloc, which will cause any concurrent readers to have their carpet yanked. At all other times, provided that the concurrent reader is not reading the entry currently being written to, reading and writing to the vector should be allowed to happen concurrently.
So, I'd want to (somehow) only lock the mutex from the write thread when I know that the write I am about to do will cause a resize operation that will realloc the vector.
Is this practical? Can I deduce based on the value returned by capacity
and the current size, for certain whether or not the next push_back
will resize?
Upvotes: 3
Views: 1807
Reputation: 3594
I am assuming you are writing into a vector by doing push_back
You can use boost shared_mutex that allows you have multiple reads and one write.
vector<string> vBuffer;
boost::shared_mutex _access;
void reader()
{
// get shared access
boost::shared_lock<boost::shared_mutex> lock(_access);
// now we have shared access
}
void writer(int index, const string& data)
{
// get upgradable access
boost::upgrade_lock<boost::shared_mutex> lock(_access);
if (vBuffer.capacity()<=index)//test here you can saefly write
{
// get exclusive access
boost::upgrade_to_unique_lock<boost::shared_mutex> uniqueLock(lock);
// now we have exclusive access
vBuffer.resize(vBuffer.2);
}
vBuffer[i]=data;
}
I adapated this example:
Example for boost shared_mutex (multiple reads/one write)?
Hope that helps, feel free to correct me if I am wrong
Upvotes: 1