I have few questions about using lock to protect my shared data structure. I am using C/C++/ObjC/Objc++
For example I have a counter class that used in multi-thread environment
class MyCounter {
private:
int counter;
std::mutex m;
public:
int getCount() const {
return counter;
}
void increase() {
std::lock_guard<std::mutex> lk(m);
counter++;
}
};
-
Do I need to use
std::lock_guard<std::mutex> lk(m);ingetCount()method to make it thread-safe? -
What happen if there is only two threads: a reader thread and a writer thread then do I have to protect it at all? Because there is only one thread is modifying the variable so I think no lost update will happen.
-
If there are multiple writer/reader for a shared primitive type variable (e.g.
int) what disaster may happen if I only lock in write method but not read method? Will 8bits type make any difference compare to 64bits type? -
Is any primitive type are atomic by default? For example write to a
charis always atomic? (I know this is true in Java but don’t know about c++ and I am using llvm compiler on Mac if platform matters)
Yes, unless you can guarantee that changes to the underlying variable
counterare atomic, you need the mutex.Classic example, say
counteris a two-byte value that’s incremented in (non-atomic) stages:and the initial value is 255.
If another thread comes in anywhere between the lower byte change
aand the upper byte changeb, it will read 0 rather than the correct 255 (pre-increment) or 256 (post-increment).In terms of what data types are atomic, the latest C++ standard defines them in the
<atomic>header.If you don’t have C++11 capabilities, then it’s down to the implementation what types are atomic.