goes out of the waiting and performs its own operation. If more than
one thread is expected on a semaphore, its up value remains null due
to the up operation but one of the threads continues to execute (in
most implementations, the choice of this thread will be random). This
operation is also called post-
signaling . Here is her dog in the doc:
void up (semaphore_t sem)
{
sem ++;
if (waiting_threads ())
wakeup (some_thread);
}
In fact, a semaphore value determines the number of threads that can pass
through that semaphore without blocking it.
When a semaphore is set to
zero initial value, it will block all threads until some thread "opens" it by
performing the up operation. Operations up and down can be performed by
any flows that have access to the semaphore.
Features Of Use Of Semaphores
Semaphores can be used to solution ' Liabilities synchronize two different
tasks.
1.
With their help, it is possible to organize mutual exclusion (to
protect the code of critical sections from execution by more than one
thread). It is most convenient to use a
binary semaphore , which can
take two values: 0 and 1. Here is
an example of implementing a
critical section using a binary semaphore:
semaphore _ t sem = 1; // at the beginning the semaphore is open
down (sem);
// critical section
up (here);
2.
With their help, you can organize the expectation of the
fulfillment of some condition. Suppose that
one needs to organize the
wait for one thread to complete another (analog of the join
operation). In this case, a semaphore with an initial value of 0
(closed) can be used. The stream
that is waiting must perform
a down operation for this semaphore and in order to signal the
completion of the stream, its completion
function requires up to
perform the same semaphore. Here is the pseudocode
( this_thread stands for current thread):
Void thread_init ()
{
this _ thread. sem = 0; // At the beginning of the stream execution the
semaphore is exposed
}
void thread _ exit ()
{
up ( this _ thread . sem ); //
wake up the pending stream, if any
}
void thread_join (thread_t thread)
{
down (thread.sem); // Waiting for thread to finish
}