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?
-
2I think a short sample would help alot to answer your question... – Meister Schnitzel Jun 28 '13 at 05:42
-
More context is needed here. – juanchopanza Jun 28 '13 at 06:14
-
1Welcome to Stack Overflow, you may want to review the [how to ask](http://stackoverflow.com/questions/how-to-ask) section to improve the phrasing of your question. – kfsone Jun 28 '13 at 06:17
-
There's no mention to multi-threading in your question, so you won't need a lock :) – Alexandru C. Jun 28 '13 at 06:57
4 Answers
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.

- 176,943
- 25
- 281
- 294
-
-
@user1764961 He asks if he needs to make the locks static when the map is static, which leads me to believe that he is asking whether the lock member needs to be static when the map member is static. A static map is shared, a non static lock is local to the object, the combination not being very lucky. If I'm reading it wrong, I'll be happy to delete the answer. – Joachim Isaksson Jun 28 '13 at 06:11
-
-
You are perfectly right, if you refer to class-static (as opposed to function-static or translation-unit-static aka internal linkage. – Arne Mertz Jun 28 '13 at 06:21
-
@ArneMertz Yes, class static... sorry for the imprecise language. – Joachim Isaksson Jun 28 '13 at 06:22
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:
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.
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 insidefoo
or class static or global. In the latter two cases, it must be locked before every call offoo
. 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; } };
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.

- 24,171
- 3
- 51
- 90
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.

- 1
- 1

- 1,501
- 17
- 22
-
-
yes I have similar code but that lock is a member variable, so I have to make it static member variable to lock static std::map? – user1393608 Jun 28 '13 at 06:23
-
@Arne Mertz won't help what? It depends on the problem you need to solve. It's possible to have lock per object - just have mutex as class member (which I wrote in this answer). – Wintermute Jun 28 '13 at 06:32
-
@user1393608 if you need _per_object_ lock - you don't need static. If you need global class lock - you need one. That's a short version :) – Wintermute Jun 28 '13 at 06:33
-
Thanks, @user1393608 I will add static before my member variable lock – user1393608 Jun 28 '13 at 06:50
No, generally you don't need a static lock.

- 673
- 7
- 21
-
Er... if he is asking what I think he is (he needs to clarify), then he most definitely needs the lock to be the same (static) storage class as the map. – Joachim Isaksson Jun 28 '13 at 05:43
-
Eh, that's why I said "generally". We don't know what exactly he wrote. – user1764961 Jun 28 '13 at 05:44
-
yes why is it so, "needs the lock to be the same (static) storage class as the map". – user1393608 Jun 28 '13 at 05:47
-
I will not delete this answer, because it is correct. Feel free to downvote as much as you like. – user1764961 Jun 28 '13 at 06:16
-
You need one lock per object that should be used synchronized and that is not threadsafe. So if there is only *one* object to synchronize, you need only *one* lock, be it global or class-static or function-static, does not matter. – Arne Mertz Jun 28 '13 at 06:18
-
Based on how the OP phrased the question, yes, it does matter. You can have global variable which is not explicitly declared as static and it will work. I bet the OP is not aware of that. – user1764961 Jun 28 '13 at 06:21