78.1k views
5 votes
OBJECTIVE This project will familiarize you with the use of pthreads, pthread mutexes and pthread condition variables. Your program will earn you no credit if it uses semaphores instead of mutexes and condition variables. THE PROBLEM A car tunnel is so poorly ventilated that it has become

User TheJosh
by
4.0k points

1 Answer

2 votes

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.

OBJECTIVE This project will familiarize you with the use of pthreads, pthread mutexes-example-1
OBJECTIVE This project will familiarize you with the use of pthreads, pthread mutexes-example-2
OBJECTIVE This project will familiarize you with the use of pthreads, pthread mutexes-example-3
OBJECTIVE This project will familiarize you with the use of pthreads, pthread mutexes-example-4
OBJECTIVE This project will familiarize you with the use of pthreads, pthread mutexes-example-5
User Asdfjklqwer
by
4.0k points