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.