Imagine a big office (your program), with many assets (shared resources) and many employees (threads). For example, all employees share one common resource - a toilet. They have agreed to use a label on a toilet's door (mutex).
When an employee wants to use the toilet he checks a label on a door (locks a mutex). If it is "engaged" he waits (blocks on a mutex), then when it is "free", he enters the toilet and changes the label to "engaged" (mutex lock succeeds). When employee finishes his business in the toilet, he goes out and changes the label to "free" (unlocks mutex).
Many people can go to the toilet at the same time, forming a queue (many threads block on a mutex). Then it is up to a company's policy (threads implementation), who is going to enter the toilet next. Usually, it is the first person in the queue (FIFO algorithm).
So, in order to pee safely, the following rules must apply:
- Everybody who wants to pee, must check the label and enter only when it is "free" with setting the label to "engaged" simultaneously (lock mutex). Breaking this rule leads to a conflict.
- After peeing, an employee must set the label to "free" (unlock mutex).
These rules, as you see, are just an agreement in the office (program logic). The label on the toilet's door (mutex) and the toilet itself (resource) are completely independent. The label can be anywhere, for example, at the helpdesk. The main thing is that everybody knows where the label is and how it should be used.
What happens if somebody in the office does not follow the agreement (some thread does not use mutex when accessing a resource)? Such a person enters the toilet without paying attention to the label. Somebody can be sitting there already, and as you can imagine, bad things could happen.
Authors: Denis Kozadaev, Sergey Lyubka. June 2007.
Correctey by: Vsevolod Stakhov, January 2014.
This is funny and a great explanation! Thanks