Synchronizing dependent actions

Because threads run concurrently, dependent actions that execute in different threads require synchronization to ensure that they execute in the correct, intended order. You must design the application to use synchronization primitives such as condition variables to ensure the desired order of execution.For example, when several threads share a queue, some threads may read from the queue (the consumer threads) while others write to the same queue (the producer threads). In this case, access to the queue must be both serialized (to keep the queue data consistent) and synchronized (so that consumers do not read from an empty queue and producers do not write to a full queue).Both conditions can be satisfied by associating a mutex queue_mutex and condition variables queue_notempty and queue_notfull with the queue. If the POSIX pthread interface is used, then each producer thread performs the steps below to insert to the queue:

pthread_mutex_lock(queue_mutex)
while queue is full
pthread_cond_wait(queue_notfull, queue_mutex)
end while
insert an item
pthread_cond_signal(queue_notempty, queue_mutex)
pthread_mutex_unlock(queue_mutex)

Meanwhile, the consumer thread performs the steps below to read from the queue:

pthread_mutex_lock(queue_mutex)
while queue is empty
pthread_cond_wait(queue_notempty, queue_mutex)
end while
remove an item
pthread_cond_signal(queue_notfull, queue_mutex)
pthread_mutex_unlock(queue_mutex)

If the consumer thread finds the queue empty, it calls the pthread_cond_wait routine on the queue_notempty condition. This call will not return until a producer thread calls pthread_cond_signal with queue_notempty. When a producer thread inserts an item, it calls pthread_cond_signal to signal that the queue_notempty condition is satisfied.Read your thread system documentation to understand what synchronization primitives are provided and how they are used.