We've mentioned several times now that tasks are meant to be programmed so that they're running in parallel. This means that, by default, they have no relation to one another in time. No assumptions can be made as to where tasks are in their execution with respect to one another – unless they are explicitly synchronized. Semaphores are one mechanism that's used to provide synchronization between tasks.
Using semaphores
Synchronization via semaphores
The following is a diagram of the abstract example we covered back in Chapter 2, Task Signaling and Communication Mechanisms:
The preceding diagram shows TaskB waiting on a semaphore from TaskA. Each time TaskB acquires the desired semaphore, it will continue...