I was reading about how schedulers work and hit something I didn’t expect.
Mutex and atomic.
I always knew they both deal with concurrency, but I never really thought about what actually happens underneath when you use them.
Mutex
So when you use a mutex, you’re working with a higher-level synchronization mechanism. You tell the runtime, “lock this section of code.”
But the thread holding that lock can still get preempted.
The OS can just kick it off the CPU mid-execution, and now it sits there holding the lock while doing nothing, while every other thread that needs it is stuck waiting.
The kernel doesn’t care that the thread happens to be holding a mutex. As far as the scheduler is concerned, it’s just another thread that used its time and got switched out.
That’s a weird thing to realize when you’ve mostly thought about a mutex as simply:
lock → do work → unlock
There is an entire scheduling system underneath that doesn’t know or care about the story you’re trying to tell with that lock.
Atomic
Atomic is a different thing entirely.
It’s not just a runtime concept. Many atomic operations are implemented using CPU atomic instructions such as LOCK XADD, LOCK CMPXCHG, or their equivalents depending on the architecture and operation.
The hardware provides the atomicity guarantee for that operation.
The important part is that another thread can’t observe the read-modify-write as a bunch of separate operations. From the perspective of the synchronization model, the operation happens atomically.
No mutex has to be acquired.
No thread has to sit there holding a lock while doing unrelated work.
And the scheduler doesn’t need to get involved just to make that single operation atomic.
Why This Matters
So if you’re building something like a flash-sale counter, an atomic decrement can be a much better fit than putting a mutex around the operation when all you actually need is an atomic update.
You don’t need to protect an entire critical section if the operation itself can be performed atomically.
That’s the part I hadn’t really appreciated before.
A mutex gives you a larger synchronization boundary.
An atomic operation gives you a very small one.
The right choice depends on what you’re actually trying to protect.
The Deeper Rabbit Hole
The deeper I go into how schedulers work, the more I realize how much is hiding under “it just works.”
The clock ticks, threads get swapped, locks get held, CPUs execute instructions, memory gets synchronized, and none of it is magic.
It’s just a lot of small decisions stacked on top of each other.
Anyway.
Just something I didn’t know last week.
References