Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Making std::mutex as static creates race-condition for the mutex itself

It may sound dummy but,Am sort of confused, I have gone through this question,when looking into it we both where in the same situation it seems, I have to make my map as static so it will be common to all instances that will be created in separate threads and I want to synchronize the functions that gonna act on my map, so i thought of making a std::mutex as static in my class like what was suggested as an answer in the given link.. in this case will there be any race-condition occur for acquiring and locking the mutex itself? is there any better way we can synchronize the functions on static map using mutex

like image 783
RaGa__M Avatar asked Aug 09 '16 21:08

RaGa__M


People also ask

Can STD mutex be static?

Currently std::mutex doesn't support static initialization. This is a regression with respect to pthread_mutex_t, which does.

Is std :: mutex fair?

On windows e.g. mutexes are mostly fair, but not always. Some implementations e.g. Thread Building Block provide special mutexes that are fair, but these are not based on the OSes native mutexes, and are usually implemented as spin-locks (which have their own caveats). Save this answer.

What is the role of std :: mutex?

std::mutex The mutex class is a synchronization primitive that can be used to protect shared data from being simultaneously accessed by multiple threads.

Does mutex need to be global?

A mutex has whatever scope you assign to it. It can be global or local again based on where and how you declare it.


1 Answers

Does Making std::mutex as static creates race-condition for the mutex itself

No, a Mutex isn't vulnerable to race-conditions. And as for initializing it as static, you are safe.

$6.7: 4: Dynamic initialization of a block-scope variable with static storage duration ([basic.stc.static]) or thread storage duration ([basic.stc.thread]) is performed the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization. If the initialization exits by throwing an exception, the initialization is not complete, so it will be tried again the next time control enters the declaration. If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization


You said:

i thought of making a std::mutex as static in my class like what was suggested as an answer in the given link.

Do that if you are trying to protect static class member variables as well. Otherwise, make it a mutable member. The fact that you said the map will be globally initialized as static is okay, since the mutex as a member variable, will follow suite.

class Map{
public:
    Map(...){}

    std::size_t size() const{
         std::lock_guard<std::mutex> lck(m_m);
         return m_size;
     }

     iterator add(....) {
         std::lock_guard<std::mutex> lck(m_m);
         ....
         return your_iterator;
     }

     ...etc

private:
    mutable std::mutex m_m; //FREE ADVICE: Use a std::recursive_mutex instead
    ...others
};

Now:

//Somewhere at global scope:

Map mp(... ...);

// NOTES
// 1. `mp` will be initialized in a thread safe way by the runtime. 
// 2. Since you've protected all Read or Write member functions of the class `Map`,
//    you are safe to call it from any function and from any thread
like image 89
WhiZTiM Avatar answered Oct 06 '22 23:10

WhiZTiM