Process Synchronization & the Critical-Section Problem

a mutex lock

A mutex (short for mutual exclusion) lock is the everyday, practical tool for protecting a critical section. Think of it as a single key hanging by a shared room: before you enter, you take the key (acquire); while you hold it, nobody else can get in; when you leave, you hang it back (release) so the next person can take it. The whole rule is just discipline: every thread that wants to touch the shared data must acquire the same mutex first and release it after. Used consistently, it gives you mutual exclusion without you having to think about atomic instructions at all.

A mutex offers two operations, conventionally acquire (or lock) and release (or unlock). acquire either succeeds immediately if the lock is free, or makes the caller wait until it becomes free; release marks it free and lets one waiter proceed. Internally the acquire is built from a hardware atomic instruction like test-and-set or compare-and-swap, so that the 'check if free and grab it' step is itself indivisible. Crucially, a correctly implemented mutex also carries the memory-ordering guarantees (acquire/release semantics) that make all the writes done inside the critical section visible to the next thread that acquires it — so you get both exclusion and correct visibility from one tool.

Two practical truths. First, a mutex protects data only by convention: it is a flag, not a fence around the variable. If even one code path modifies the shared data without holding the mutex, the protection is gone. The mutex and the data it guards are linked only in the programmer's mind, so the discipline must be perfect. Second, mutexes come in two waiting styles, and choosing wrong hurts. A spinlock-style mutex busy-waits (spins) and is right when the wait will be very short; a blocking mutex puts the waiting thread to sleep and is right when the wait may be long, since sleeping frees the CPU for other work. Forgetting to release a mutex (especially on an early return or an exception) is a classic source of deadlock.

acquire(m); balance = balance + deposit; release(m). Every thread that touches balance brackets its access with the same mutex m, so the read-modify-write can never interleave with another thread's. Forget the acquire in one place and the whole guarantee collapses.

Acquire -> touch shared data -> release. Always the same mutex, always paired.

A mutex is a convention, not a wall: it guards data only if every accessor locks it. Forgetting to release (on an early return or exception) is a top cause of deadlock.

Also called
mutexlock互斥量