You didn't say what language. I'm going to pretend it's C++.
I use a different mutex for each variable...
That sounds suspicious.
Your threads communicate with each other by updating shared state. A mutex, when correctly used, does two things:
- It ensures that after thread A updates the shared state, other threads will be able to see what was changed, and
- It ensures that the other threads will not see the change until the change is complete.
If a thread can meaningfully change the state of the program by writing a single uint16_t
value, then you don't need a mutex for that. Just change the type of the variable to atomic<uint16_t>.
Making it atomic will ensure that other threads can see the change. And, you don't have to worry about the completeness. That's trival: Every other thread must either see the old value or the new value. There's no other possibilities.
You need a mutex
when the situation is more complicated. Suppose you have three variables:
int a, b, c;
And, suppose that there's a rule, that a+b+c
must always equal zero. A rule like that is called an invariant. Now, there's no way a thread can legally change just one of those three variables. But, if it tries to change two of them in a row, there's always the possibility that some other thread could look at them at just the wrong moment, and it could see them in an inconsistent state (i.e., in a state that breaks the invariant.)
Making the variables atomic
won't fix the problem. And, making a separate mutex for each variable won't fix the problem. You need one mutex whose purpose is to protect the invariant. You need every thread that updates a
, b
, and/or c
to lock that one mutex whenever it's making a change; and you need every thread that expects the invariant to be true to lock the same mutex whenever it looks at them.