Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a standard map that is thread safe

Tags:

In my current scenario speed is essential I have a map that is only being read by multiple threads and this works fine. Now a requirement came up that may require writing to the static map once in a while while the maps are being read by other threads. I believe this is a game changer since I would need to lock my maps for thread safety.This poses a problem since I have multiple threads 10-12 threads that are going to be reading the map. If one map takes a lock on the map (since its reading) I believe the lock would be necessary since something might be written to a map. Anyways as I stated earlier that if one map is reading then other maps wont have the parallel reading access to the map like they did earlier. Is there any way by which I can circumvent this issue ?

like image 484
MistyD Avatar asked Oct 02 '13 17:10

MistyD


2 Answers

You can use a shared_mutex beside your map to acquire shared or unique access. Generally, a write operation will require unique access, while read operations will require shared access.

Any number of threads can acquire shared access, as long as no threads are holding unique access. If a thread attempts to acquire unique access, it waits until all shared access is released.

The standard library and Boost provide shared_lock<T> and unique_lock<T> for scope-bounded acquisition of a shared_mutex.

Beware that some people claim shared_mutex performs poorly, though I haven't seen any evidence or strong analysis to support these claims. It may be worth looking into, if it matters to you.

like image 158
Collin Dauphinee Avatar answered Sep 21 '22 03:09

Collin Dauphinee


just for your c++ pleasure, read this book, you'll find WAY more worth than the money spent, your concurrency world will get open wide
C++-Concurrency in Action Practical Multithreading
the books deal with all sort of issues and practical solutions between thread's data sharing, how to wake threads, thread pools creation and more...more...and more

here an example of sharing data between threads without using atomic or shared_locks

template<class T>
class TaskQueue
{
public:
    TaskQueue(){}
    TaskQueue& operator = (TaskQueue&) = delete;

    void Push(T value){
        std::lock_guard<std::mutex> lk(mut);
        data.push(value);
        condition.notify_one(); //if you have many threads trying to access the data at same time, this will wake one thread only
    }

    void Get(T& value){
        std::unique_lock<std::mutex> lk(mut);
        condition.wait(lk, [this]{ return !data.empty(); }); // in this case it waits if queue is empty, if not needed  you can remove this line
        value = data.front();
        data.pop();
        lk.unlock();
    }

private:
    std::mutex mut;
    std::queue<T> data; //in your case change this to a std::map
    std::condition_variable condition;
};
like image 32
LemonCool Avatar answered Sep 19 '22 03:09

LemonCool