Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mutex pattern where multiple threads can have read-only access

I have a list of Dinosaur objects, that can be added to, removed from, and the dinosaurs themselves need to be fed. This all happens in a highly multi-threaded environment, so the list is mutex protected.

static Mutex s_dinosaurMutex;
static vector<Dinosaur> s_dinosaurList;

void AddDinosaur(const Dinosaur& dinosaur)
{
    s_dinosaurMutex.Lock();
    s_dinosaurList.push_back(dinosaur);
    s_dinosaurMutex.Unlock();
}

void RemoveDinosaur(const Dinosaur& dinosaur)
{
    s_dinosaurMutex.Lock();

    vector<IMadderReceiver*>::iterator it = find(s_dinosaurList.begin(), s_dinosaurList.end(), dinosaur);
    if (it != s_dinosaurList.end())
        s_dinosaurList.erase(it);

    s_dinosaurMutex.Unlock();
}

void FeedDinosaur(const Dinosaur& dinosaur)
{
    s_dinosaurMutex.Lock();

    vector<IMadderReceiver*>::iterator it = find(s_dinosaurList.begin(), s_dinosaurList.end(), dinosaur);
    if (it != s_dinosaurList.end())
        (*it).Feed(); // Feeding a dinosaur can take a long time, ~ 1 second

    s_dinosaurMutex.Unlock();
}

Now the problem is in the feeding. This can take a long time, but it's absolutely fine if multiple threads feed the same (or a different) dinosaurs at the same time. The feeding process should therefore not stall other FeedDinosaur calls, though it should stall for Add and Remove calls, and wait for those to finish. The behaviour at the moment is that many threads are lining up queuing in order to Feed the dinosaurs, which makes the system grind to a hold.

Is there a particular (mutex-like) design patterns that allows this type of behaviour of ok-ing threads that require read-only access?

like image 716
Yellow Avatar asked Feb 11 '26 14:02

Yellow


1 Answers

This is a reader-writer mutex; Boost and C++ use the more general term "shared mutex" because it can be used for patterns other than multiple reader-single writer.

Boost.Thread has shared_mutex since version 1.35.0 (Reader/Writer Locks in C++). C++ has shared_timed_mutex since C++14 and will have shared_mutex in C++17; until that is available you can use C++14 shared_timed_mutex and just not use the timeout mechanism.

In your writer thread, lock the shared mutex for unique access (use a unique_lock); in your reader threads, lock the shared mutex for shared access (use a shared_lock).

like image 80
ecatmur Avatar answered Feb 14 '26 04:02

ecatmur



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!