Answer:
Check the explanation
Step-by-step explanation:
/*
This program will simulate a tunnel with a limit of how many cars may move through it,
and will also simulate the cars going north and south-bound through the tunnel. We will
use pthreads, pthread mutexes, and pthread condition variables to simulate this.
*/
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
using namespace std;
#define MAXTHREADS 128
static int maxCarsInTunnel;
static int maxNCarsInTunnel;
static int maxSCarsInTunnel;
static int totalNCars;
static int totalSCars;
static int currentCarsInTunnel;
static int currentNCarsInTunnel;
static int currentSCarsInTunnel;
static int numCarsWaiting;
static pthread_mutex_t lockAccess = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
void *northCar(void *arg);
void *southCar(void *arg);
struct car {
int carNo;
int travelTime;
bool waited;
};
int main() {
pthread_t cartid[MAXTHREADS];
int storage = 0;
cin >> maxCarsInTunnel;
cin >> maxNCarsInTunnel;
cin >> maxSCarsInTunnel;
cout << "Maximum number of cars in the tunnel: " << maxCarsInTunnel << endl;
cout << "Maximum number of northbound cars: " << maxNCarsInTunnel << endl;
cout << "Maximum number of southbound cars: " << maxSCarsInTunnel << endl;
unsigned int arrival_time;
char direction;
unsigned int traversal_time;
struct car argList;
while (cin >> arrival_time >> direction >> traversal_time) {
sleep(arrival_time);
argList.travelTime = traversal_time;
argList.waited = false;
if (direction == 'N') {
totalNCars++;
argList.carNo = totalNCars;
pthread_create(&cartid[storage], NULL, northCar, (void *) &argList);
}
else if (direction == 'S') {
totalSCars++;
argList.carNo = totalSCars;
pthread_create(&cartid[storage], NULL, southCar, (void *) &argList);
}
storage++;
}
for (int i = 0; i < storage; i++) {
pthread_join(cartid[i], NULL);
}
cout << totalNCars << " northbound car(s) crossed the tunnel." << endl;
cout << totalSCars << " southbound car(s) crossed the tunnel." << endl;
cout << numCarsWaiting << " car(s) had to wait." << endl;
return 0;
}
void *northCar(void* arg) {
int tunnelTime;
int carNum;
bool wait;
struct car *argptr;
argptr = (struct car *) arg;
tunnelTime = argptr->travelTime;
carNum = argptr->carNo;
wait = argptr->waited;
pthread_mutex_lock(&lockAccess);
cout << "Northbound car # " << carNum << " arrives at the tunnel." << endl;
while (currentNCarsInTunnel >= maxNCarsInTunnel || currentCarsInTunnel >= maxCarsInTunnel) {
if (wait == false) {
wait = true;
numCarsWaiting++;
}
pthread_cond_wait(&cond, &lockAccess);
}
currentNCarsInTunnel++;
currentCarsInTunnel++;
cout << "Northbound car # " << carNum << " enters the tunnel." << endl;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&lockAccess);
sleep(tunnelTime);
pthread_mutex_lock(&lockAccess);
cout << "Northbound car # " << carNum << " exits the tunnel." << endl;
currentNCarsInTunnel--;
currentCarsInTunnel--;
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&lockAccess);
}
void *southCar(void* arg) {
int tunnelTime;
int carNum;
bool wait;
struct car *argptr;
argptr = (struct car *) arg;
tunnelTime = argptr->travelTime;
carNum = argptr->carNo;
wait = argptr->waited;
pthread_mutex_lock(&lockAccess);
cout << "Southbound car # " << carNum << " arrives at the tunnel." << endl;
while (currentSCarsInTunnel >= maxSCarsInTunnel || currentCarsInTunnel >= maxCarsInTunnel) {
if (wait == false) {
wait = true;
numCarsWaiting++;
}
pthread_cond_wait(&cond, &lockAccess);
}
currentSCarsInTunnel++;
currentCarsInTunnel++;
cout << "Southbound car # " << carNum << " enters the tunnel." << endl;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&lockAccess);
sleep(tunnelTime);
pthread_mutex_lock(&lockAccess);
cout << "Southbound car # " << carNum << " exits the tunnel." << endl;
currentSCarsInTunnel--;
currentCarsInTunnel--;
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&lockAccess);
}
Kindly check the attached images below to see the code screenshot and code output.