Reputation: 14984
I have a resource (vector, list, whatever) that I am trying to give access to multiple writers/readers.
I'm not sure how to go about this to achieve best performance, ie, minimal amount of locking for a reader if the data structure is locked. Would it be better to use two locks, one called readmutex and the other called writemutex?
So for example:
struct Foo {
mutex writemutex_;
mutex readmutex_;
vector<string> data_;
void write(string data)
{
lock_guard<mutex> locker(writemutex_);
data_.emplace_back(move(data));
}
string get(int index) const {
// I don't need to lock for read, but what if the data is being written?
// and so should I lock lockmutex_? If so, then readmutex_ is unnecessary?
// is there some cleaver way that I can avoid readers from being blocked?
return data_[index];
}
};
what other synchronization techniques can I use here?
Upvotes: 3
Views: 186
Reputation: 179779
To answer your primary question: No, using two locks isn't better. It's in fact incorrect. You need the write lock to prevent races, and while holding the write lock there's no need for any additional read lock.
The other answers do have the correct alternative (shared_mutex, which implements a reader-write lock), but don't explain why it's needed.
Upvotes: 0
Reputation: 18905
You can use shared_mutex
which is available in boost and will be part of C++14.
struct Foo
{
using mutex = boost::shared_mutex;
using write_lock = boost::unique_lock<mutex>;
using read_lock = boost::shared_lock<mutex>;
mutable mutex mutex_;
vector<string> data_;
void write(string data)
{
write_lock lock{ mutex_ };
data_.emplace_back(move(data));
}
string get(int index) const
{
read_lock lock{ mutex_ };
return data_[index];
}
};
Upvotes: 1
Reputation: 1645
You need Readers–writer lock. But you should take into account that in some scenaries rw lock may be more slowly than exclusive lock
There are a lot of implementations, e.g. in boost. WinAPI also has one (since Vista or Server 2008)
Upvotes: 2