#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); } }