There are specific operations that are used to signal whether or not a condition has been met when working with phtreads/processes.
In shell lab, we used sigsuspend, along with a mask that contained the signals we didn't want to wait on (ie the signals that should awaken the process). So, if we had a job running in the foreground (ie the parent process (the shell) is waiting on a child process (the job) to terminate/stop), we would wait for the job to terminate/stop, while maintaining the ability to reap other terminated/stopped processes.
With pthreads, a similar operation would be pthread_cond_wait. This can be used along with pthread_mutex_lock to block an operation until a condition was met. This was the approach that was used in implementing the thread-safe worker queue that we used in the elastic web server. There are two aspects that make this implementation tricky:
We should use a lock on the data structure (a vector; STL has no built-in synchronization primitives) whenever we are adding/removing jobs. These locks should be set at the beginning of the calls to get_work/put_work and released at the end.
However, if the work queue is empty, then calling the get_work operation would cause the code to deadlock (if we only used locks), since the get_work operation needs to check whether the queue is empty. It will not be able to proceed and will wait until a put_work operation replenishes the queue.
Unfortunately, since the get_work operation has acquired the lock, there is no way for the put_work operation to acquire the lock. Hence, we are in a state of deadlock.
In order for this to work, in the case where get_work is called on an empty queue
In the code for get_work, we use the pthread_cond_wait operation, which releases the lock and blocks the thread, until a signal is received from a call to pthread_cond_signal from a different thread. On receiving the signal, the blocked thread will awaken, reacquire the lock and will check the loop condition again; it will break out of the loop when the condition fails.
Crucially, the condition needs to be checked while the thread has ownership of the lock.
This comment was marked helpful 2 times.
DunkMaster
When the execution resources are scarce, blocking is better than busy waiting. But in other conditions, it is not necessarily true
There are specific operations that are used to signal whether or not a condition has been met when working with phtreads/processes.
In shell lab, we used
sigsuspend
, along with a mask that contained the signals we didn't want to wait on (ie the signals that should awaken the process). So, if we had a job running in the foreground (ie the parent process (the shell) is waiting on a child process (the job) to terminate/stop), we would wait for the job to terminate/stop, while maintaining the ability to reap other terminated/stopped processes.With pthreads, a similar operation would be
pthread_cond_wait
. This can be used along withpthread_mutex_lock
to block an operation until a condition was met. This was the approach that was used in implementing the thread-safe worker queue that we used in the elastic web server. There are two aspects that make this implementation tricky:get_work
operation would cause the code to deadlock (if we only used locks), since theget_work
operation needs to check whether the queue is empty. It will not be able to proceed and will wait until a put_work operation replenishes the queue.In order for this to work, in the case where
get_work
is called on an empty queue In the code forget_work
, we use thepthread_cond_wait
operation, which releases the lock and blocks the thread, until a signal is received from a call topthread_cond_signal
from a different thread. On receiving the signal, the blocked thread will awaken, reacquire the lock and will check the loop condition again; it will break out of the loop when the condition fails.Crucially, the condition needs to be checked while the thread has ownership of the lock.
This comment was marked helpful 2 times.
When the execution resources are scarce, blocking is better than busy waiting. But in other conditions, it is not necessarily true
This comment was marked helpful 0 times.