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.