Locks, Mutexes, and Semaphores: Types of Synchronization Objects (2014)
justsoftwaresolutions.co.uk
justsoftwaresolutions.co.uk
This article is a bit dated. It's all about locks that aren't directly connected to the data they lock. With the advent of Rust, people are finally getting that "what locks what" is something the language should address. C/C++ locking is a legacy of the "that's an operating system problem" era of locking.
It's not just a safety issue. If you need to fence something, it helps if the compiler knows what to fence.
I am already familiar with much of this, but I haven't seen it explained quite as concisely, or generically.