5. Semaphore Object
The PiThreads class Semaphore
provides both binary and counting semaphore services to the user of the
library. The class semaphore is defined
in the header file semaphore.h and must be included after the inclusion of the
threads.h header file and the #define WIN or #define POSIX statement. The PiThreads semaphore object is process
local and cannot be used to synchronize across multiple processes. The public
member functions of the class Semaphore which serve as the interface to the
semaphore object can be seen below.
class Semaphore
{
public:
Semaphore();
Semaphore(long initial_count);
Semaphore(long intial_count, long max_count);
~Semaphore();
void Post();
//Increase semaphore count
void Wait(); //if non-zero, sem val decremented
};
The semaphore object provides three
ways to initialize a semaphore object through the three constructors. The default constructor Semaphore
initializes a binary semaphore with an initial count of one. This count associated with a binary
semaphore can reach a maximum value of one.
The constructor Semaphore(long initial_count) instantiates a semaphore
object with an initial and maximum count corresponding to the value passed to
the initial_count parameter. If a value
of zero is passed to this constructor, a binary semaphore with an initial count
of zero and a maximum count of one is created.
For all other circumstances, the constructor Semaphore(long
initial_count long max_count) creates a semaphore with an initial count as
specified by the parameter initial_count and a maximum count value as indicated
by the parameter max_count. A thread
calling the semaphore object’s member
function Wait() executes a semaphore wait operation. Post() is called to increment the cunt associated with a
semaphore.
The following code shows examples of
all means of semaphore initialization.
Semaphore BSemaA; //Binary semaphore with initial/.max count
of one
Semaphore BSemaB(0); //Binary semaphore with initial count of
zero
//and max count of one
Semaphore CSemaA(3); //Counting semaphore with initial/max
count of three
Semaphore CSemaB(0,5); //Counting semaphore with an initial count
of zero
//and a maximum count
of five
The
first semaphore, BSemaA is initialized as a binary semaphore with an initial
count of one by the default constructor.
The second semaphore BSemaB is initialized as a binary semaphore with an
initial count of zero. The semaphore
CSemaA is initialized as a counting
semaphore with an initial and maximum count of three. This is done with the Semaphore(long initial_count)
constructor. The final semaphore is
initialized with an initial count of zero and a maximum count value of
five. This is done with the Semaphore(long
initial_count long max_count) constructor.
The following code snippet shows how threads can perform wait and post
operations on a semaphore.
#define WIN or #define POSIX
#include<thread.d>
#include<semaphore.h>
Semaphore BSema;
class ThreadDemo : public
Thread
{
public:
ThreadDemo() : Thread() {}
void EntryRoutine(void)
{
BSema.Wait() //Wait on
semaphore protected resource
///Utilize resource
BSema.Post()
//Finished with resource, post to semaphore
}
void ExitRoutine(void) {}
};
void main()
{
int cnt;
ThreadDemo SemUsers[5];
for(cnt = 0; cnt < 5;
cnt++)
SemUsers.Create();
for(cnt = 0; cnt < 5;
cnt++)
SemUsers.Join();
}
In this example, five threads are
created which wait on a binary semaphore.
After waiting on the the semaphore, the thread accesses a protected
resource. Then when the resource is
freed, the thread calls Post() to the binary semaphore to permit another thread
access to the resource.