stewart99
stewart99

Reputation: 14984

c++ two locks better than one?

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

Answers (3)

MSalters
MSalters

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

hansmaad
hansmaad

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

sliser
sliser

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

Related Questions