Do we need to have static lock for static member variable of the class in c++

被刻印的时光 ゝ 提交于 2019-12-12 05:16:31

问题


I have a static map as a member variable of my class. Do we need to have static lock when we have to access this map?


回答1:


If your std::map instance is declared class static, then your lock needs to be class static too.

Consider two threads working against separate objects using the map when the lock is a non static member but the map is.

  • Object 1 locks the local lock and starts manipulating the shared map.
  • Object 2 locks its local lock (it's a separate lock, remember) and starts manipulating the shared map.
  • Boom/crash/burn

If the lock is class static, the two objects will share the lock, and the above scenario will work well, only one thread can lock at a time.

There are of course other ways to share a lock without using static, but that does not seem to be what you're asking.




回答2:


You need exactly one mutex per object that has to be used in a synchronized way. Having multiple mutexes for one object will lead to race conditions as shown by the example Joachim Isaksson has given in his answer.

There are different ways of static variables:

  1. class static (wich is probably what you mean):

    class X {
      static map<A,B> mMap;
    };
    

    You have exactly one object system-wide. In this case, the mutex for the map should be class static as well and should be locked whenever the map is used in a way that needs to be synchronized. Keep in mind, that initialization of class static members is not threadsafe.

  2. function local static:

     class X {
       void foo() {
         static map<A,B> theMap{ /* ... */ };
       }
     };
    

    You have one object system-wide, regardless of wether foo itself is class static or not. Initialization of that object is guaranteed to be threadsafe. You need exactly one mutex system-wide as well. That mutex should be either static inside foo or class static or global. In the latter two cases, it must be locked before every call of foo. That is the classic usecase of the Meyers singleton:

     class X {
       static mutex mapMutex;
    
       static map<A,B>& getMap() {
         static map<A,B> theMap{ /* ... */ };
         return theMap;
       }
    
       void useMap() {
         lock myLock(mutex);
         getMap()[a] = b;
       }
     };
    
  3. translation unit static ("global static")

     static map<A,B> gMap;
    
     class X { /* ... */ };
    

    You have one object inside every translation unit that has such a declaration, i.e. if it is inside a .cpp, you get one object. If it is inside a header, you get one object for every translation unit that includes that header. The mutex for that object should be translation unit static as well, as you need as many mutexes as there are objects. However, I would not recommend using that kind of static variables in a multithreaded environment.




回答3:


First of all you should consider reading smth on static (Try this, maybe). That's because meaning of static depends on context.

But that's probably a complication, I believe you have something like this:

class A {
    private:
        static std::map....

    public:
        void doSomethingWithMap() {
            //lock mutex

            //some action with map

            //unlock mutex
        }
}

If that's the case, then you might want to have your mutex as a member of this class. That's the point - it depends on the scope you need. If you need to lock globally across all the objects of this class - you should consider using static class member, if you want to have lock per object - you should settle with just a class member.




回答4:


No, generally you don't need a static lock.



来源:https://stackoverflow.com/questions/17357909/do-we-need-to-have-static-lock-for-static-member-variable-of-the-class-in-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!