semDemo.cpp

URL: https://mirkwood.cs.edinboro.edu/~bennett/class/cmsc4000/spring2026/notes/ch6/code/semDemo.cpp
 
#include <iostream>

// perror
#include <stdio.h>


// for semaphores
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>

// for usleep
#include <unistd.h>

// for wait
#include <sys/wait.h>

using namespace std;

const string SEMAPHORE_NAME{"/BENNETT_SEM"};

sem_t * lock;

void DoProcess(int id);

int main() {

     int processes{4};

     int oflags {O_RDWR | O_CREAT};
     mode_t mode {S_IRUSR | S_IWUSR};

     lock = sem_open(SEMAPHORE_NAME.c_str(), oflags, mode, 1);
     if(nullptr == lock) {
         perror("sem_open: ");
     }

     for(int i =0; i < processes; ++i) {
          if (fork() == 0) {
              srand(time(nullptr)+ i);
              DoProcess(i);
              return 0;
          }
     }

     for(int i =0; i < processes; ++i) {
        wait(nullptr);
     }

     sem_close(lock);
     sem_unlink(SEMAPHORE_NAME.c_str());

     return 0;

}

const int SLEEP_MAX{100000};
const int SLEEP_MIN{1000};

void DoProcess(int id) {
    int status;
    int value;

    for(int i =0; i < 5; ++i) {
        // sleep a random amount of time
        cout << "Process " << id << " sleeping." << endl ;
        usleep(rand() % SLEEP_MAX + SLEEP_MIN);
        cout << "Process " << id << " \t ready to work" << endl;

        // try to be the only worker, possibly block
        status = sem_wait(lock);
        if (status == -1) {
            perror("sem_wait");
        }

        cout << "Process " << id << " \t\t  working" << endl;
        sem_getvalue(lock, &value);
        cout << "The semaphore value is " <<  value << endl;
        usleep(rand() % SLEEP_MAX + SLEEP_MIN);

        // allow others to work
        status = sem_post(lock);
        if (status == -1) {
            perror("sem_post");
        }

        cout << "Process " << id << " \t done working" << endl;
        usleep(rand() % SLEEP_MAX + SLEEP_MIN);
    }
}