Now, that you have two simple rules. Some other ones (left unjustified here):
don't use a C int to protect the data ! Always use a mutex
(or a semaphore if you know how it works) ! It is a common fault (and
sometimes not a fault). This is architecture dependent ! The final
operation behind a mutex MUST be atomic, really atomic. Therefore,
it should finish by a test-and-set _hardware_ instruction. I don't
think C guarantees its test-and-set language ops. to be atomic at the
hardware level... So you must use a dedicated library. (NB: This is
why a mutex is never called an int...) Don't try to implement a mutex
yourself, it may be tricky (it may work on x86 with gcc and not on
alpha with cc for example).
don't do this in too many very concurrent threads:
while (1) {
MutexGet(a_mutex);
/* some work */
MutexRelease(a_mutex);
}
if you are not sure that a "schedule" entry point may appear
in the /* some work */ (a system call for example). Use semaphores
(or verify the "semantic" of mutexes). In this case, you may finish
with a new "starvation" problem: on preemptive systems you only create
a performance slowdown, on real-time system, some threads will never
execute.
(NB: This problem is very rare on real systems. In fact I don't know
any system on which it appears. But this is a symptom showing that a
mutex is _not_ a semaphore with initial value of 1. Theoretically at
least, in practice, it is always implemented in this way, and that's
why you never face the problem ;-)
be careful on our Unix systems... We don't have true parallel
systems, we have time-sharing deterministic systems. This means
that your program may work _perfectly_, on all the runs you can try,
and _not_ be thread safe. This is simply because, with your environment,
the deadlocks or data corruption conditions never occur. If you change
the workload, or the time-slice, or something else, it may fail. These
faults are _very_very_very_ difficult to identify a posteriori. The best
solution is to READ the code and check that you have no obscure zone
that you don't understand. (NB: This a general good coding practice
by the way: I know that, I rarely do so and I have lots of bugs. :-)
If you have more precise questions or comments, you are welcome,
of course.
Next
PreviousContents