Please fill in the YOUR CODE HERE blocks for trainLine.cpp and provide a sample output. The other answers to this question are incorrect and do not complie so please do not copy/paste from them.
Four trains of varying speeds run north-and-south on their own tracks. They visit different the two stations at either end: northTerminal after going north and southTerminal after going south.
Because each train runs on its own track, they will not collide on the tracks. However, both station can only handle one train at a time. So if two trains are ever at the same station at the same time then there will be a CRASH.
More specifically, it is not the actual Station instance that should be locked, rather, it is the act of arrive()-ing and leave()-ing the Station that should be locked.
Each train is implemented with its own thread. Please make the trains run both safely and on time.
Note: Besides the C++ code in Station.h and trainLine.cpp, this program requires you to give short answers for (b), (d) and (f) in the comments. Be sure these answers are clearly labeled!
Making the Train Line multi-threaded
Right now not much will happen. Therefore, please finish the following:
Finish main() to make and join the Threads.
I already have created NUM_TRAINS for you. They are in
trainArray[].
Please make 'NUM_NORTHERNLY_TRAINS' threads (tidArray[0] to
tidArray[NUM_NORTHERNLY_TRAINS-1]) run 'initiallyNorthernly()'.
Each thread should get a pointer to its own Train instance
(trainArray[0] to trainArray[NUM_NORTHERNLY_TRAINS-1], this is an
array of POINTERS to trains, not trains themselves).
Please make 'NUM_SOUTHERNLY_TRAINS' threads (tidArray[NUM_NORTHERNLY_TRAINS] to tidArray[NUM_TRAINS-1]) run 'initiallySouthernly()'. Each thread should get a pointer to its own Train instance (trainArray[NUM_NORTHERNLY_TRAINS] to trainArray[NUM_TRAINS-1], this is an array of POINTERS to trains, not trains themselves).
Then, please wait for the trains to finish. Please recycle their
memory by getting the pointers to them and doing a delete() on
them.
Finish initiallyNorthernly().
In a loop NUM_LOOPS times, make the Train passed to the
function:
arrive() at northTerminal
leave() from northTerminal
do pause() on the Train object
arrive() at southTerminal
leave() from southTerminal
pause() on the Train object
The function must point to the Train it used.
Finish initiallySouthernly().
In a loop NUM_LOOPS times, make the Train passed to the
function:
arrive() at southTerminal
leave() from southTerminal
do pause() on the Train object
arrive() at northTerminal
leave() from northTerminal
do pause() on the Train object
The function must point to the Train it used.
STOP! Now your program is multi-threaded. How does it behave?
Run it like this once to make sure it runs:
$ ./trainLine 1
then run it 20 times:
$ ./trainLine 1 | grep CRASH
$ ./trainLine 2 | grep CRASH
$ ./trainLine 3 | grep CRASH
$ ./trainLine 4 | grep CRASH
$ ./trainLine 5 | grep CRASH
$ ./trainLine 6 | grep CRASH
$ ./trainLine 7 | grep CRASH
$ ./trainLine 8 | grep CRASH
$ ./trainLine 9 | grep CRASH
$ ./trainLine 10 | grep CRASH
$ ./trainLine 11 | grep CRASH
$ ./trainLine 12 | grep CRASH
$ ./trainLine 13 | grep CRASH
$ ./trainLine 14 | grep CRASH
$ ./trainLine 15 | grep CRASH
$ ./trainLine 16 | grep CRASH
$ ./trainLine 17 | grep CRASH
$ ./trainLine 18 | grep CRASH
$ ./trainLine 19 | grep CRASH
$ ./trainLine 20 | grep CRASH
What do you notice?
Please answer this in the top comment in trainLine.cpp
Making the Station instances thread-safe
Make your program thread-safe my adding a pthread_mutex_t to
class Station.
Initialize it in the constructor.
Get rid of it in the destructor (~Station()).
Use it in both arrive() and leave(). Important: You a locking the
act of both arrive()-ing and leave()-ing, not the Station
itself!
STOP! Now your program is thread safe. How does it behave?
Run it like this once to make sure it runs:
$ ./trainLine 1
then run it 10 times:
$ ./trainLine 1
$ ./trainLine 2
$ ./trainLine 3
$ ./trainLine 4
$ ./trainLine 5
$ ./trainLine 6
$ ./trainLine 7
$ ./trainLine 8
$ ./trainLine 9
$ ./trainLine 10
What do you notice?
Please answer this in the top comment in trainLine.cpp
Making the Train Line functional
Make your program functional by adding a pthread_cond_t to class
Station.
Initialize in the constructor.
Get rid of in the destructor (~Station()).
Use it in both arrive() and leave().
STOP! What is the minimum number of conditions that you need? How
does it behave?
Run it like this once to make sure it runs:
$ ./trainLine 1
then run it 20 times:
$ ./trainLine 1 | grep CRASH
$ ./trainLine 2 | grep CRASH
$ ./trainLine 3 | grep CRASH
$ ./trainLine 4 | grep CRASH
$ ./trainLine 5 | grep CRASH
$ ./trainLine 6 | grep CRASH
$ ./trainLine 7 | grep CRASH
$ ./trainLine 8 | grep CRASH
$ ./trainLine 9 | grep CRASH
$ ./trainLine 10 | grep CRASH
$ ./trainLine 11 | grep CRASH
$ ./trainLine 12 | grep CRASH
$ ./trainLine 13 | grep CRASH
$ ./trainLine 14 | grep CRASH
$ ./trainLine 15 | grep CRASH
$ ./trainLine 16 | grep CRASH
$ ./trainLine 17 | grep CRASH
$ ./trainLine 18 | grep CRASH
$ ./trainLine 19 | grep CRASH
$ ./trainLine 20 | grep CRASH
What do you notice?
Please answer this in the top comment in Station.h
Sample output
When the trainLine starts, it should say something like:
$ ./trainLine
Thomas the Tank-Engine leaving the trainyard.
Engine No. 9 leaving the trainyard.
California Zephyr leaving the trainyard.
Tokaido Shinkansen leaving the trainyard.
Thomas the Tank-Engine arriving at North Station
California Zephyr arriving at South Station
Thomas the Tank-Engine leaving North Station
California Zephyr leaving South Station
Engine No. 9 arriving at North Station
Tokaido Shinkansen arriving at South Station
Engine No. 9 leaving North Station
Tokaido Shinkansen leaving South Station
. . .
When the trainLine ends, it should say something like:
. . .
Engine No. 9 arriving at North Station
Engine No. 9 leaving North Station
Thomas the Tank-Engine arriving at North Station
Thomas the Tank-Engine leaving North Station
Engine No. 9 arriving at South Station
Engine No. 9 leaving South Station
Thomas the Tank-Engine arriving at South Station
Thomas the Tank-Engine leaving South Station
Thomas the Tank-Engine going back to the trainyard
Engine No. 9 going back to the trainyard
California Zephyr going back to the trainyard
Tokaido Shinkansen going back to the trainyard
$
/*-------------------------------------------------------------------------*
*---
---*
*--- Train.h
---*
*---
---*
*--- This file declares a class that implements a Train
object. ---*
*---
---*
*--- ---- ---- ----
---- ---- ---- ----
---- ---*
*---
---*
*---
---*
*-------------------------------------------------------------------------*/
class Train
{
// I. Member vars:
// PURPOSE: To hold the name of '*this' Train.
std::string name_;
// PURPOSE: To hold the time it takes '*this' Train to go from
one
// Station to another (in microseconds).
int pauseTimeUsecs_;
public :
// PURPOSE: To initialize '*this' Train to have name 'newName' and
to have
// transit time between platforms
'newPauseTimeUsecs'. Also notes to
// std::cout that '*this' Train is leaving the
trainyard. No return
// value.
Train (const
std::string& newName,
int
newPauseTimeUsecs
)
{
name_ = newName;
pauseTimeUsecs_ = newPauseTimeUsecs;
std::cout << getName() << " leaving the
trainyard.\n";
}
// PURPOSE: To release resources. Also notes to std::cout that
'*this'
// Train is arriving back at the trainyard. No
parameters. No return
/// value.
~Train ()
{
std::cout << getName() << " going back to the
trainyard\n";
}
// PURPOSE: To return the name of '*this' Train. No
parameters.
const std::string&
getName ()
const
{ return(name_); }
// PURPOSE: To make '*this' Train wait while it transits between
platforms.
// No parameters. No return value.
void pause ()
const
{
usleep(pauseTimeUsecs_);
}
};
/*-------------------------------------------------------------------------*
*---
---*
*--- Station.h
---*
*---
---*
*--- This file declares a class that implements a
Station ---*
*--- object at which Train objects arrive, pause, and
then leave. ---*
*---
---*
*--- ---- ---- ----
---- ---- ---- ----
---- ---*
*---
---*
*---
---*
*-------------------------------------------------------------------------*/
class Station
{
// I. Member vars:
// PURPOSE: To hold the name of '*this' Station.
std::string name_;
// PURPOSE: To point to the Train object currently at '*this'
Station
// (if there is one).
Train* trainPtr_;
public :
// IV. Constructor(s), assignment op(s), factory(s) and
destructor:
// PURPOSE: To initialize '*this' Station to have name 'newName'
and
// and no Train. No return value.
Station (const
std::string& newName
)
{
name_ = newName;
trainPtr_ = NULL;
}
// PURPOSE: To release resources. No parameters. No return
value.
~Station ()
{
}
// PURPOSE: To return the name of '*this' Station. No
parameters.
const std::string&
getName ()
const
{
return(name_);
}
// PURPOSE: To return a pointer to the Train object currently at
'*this'
// Station (if there is one).
Train* getTrainPtr
()
const
{
return(trainPtr_);
}
// PURPOSE: To let '*newTrainPtr' arrive at '*this' Station. No
return
// value.
void arrive
(Train* newTrainPtr
)
{
while (getTrainPtr() != NULL)
{
std::cout << getTrainPtr()->getName()
<< " is at " <<
getName()
<< ", " <<
newTrainPtr->getName()
<< " must wait.\n";
usleep(10) + rand() % 10;
}
std::cout << newTrainPtr->getName() << " arriving at " << getName() << "\n";
if (getTrainPtr() != NULL)
std::cout << newTrainPtr->getName() << " and "
<<
getTrainPtr()->getName() << " CRASHED at "
<< getName() <<
std::endl;
trainPtr_ = newTrainPtr;
usleep(10 + rand() % 10);
}
// PURPOSE: To let the Train object currently at '*this' Station
leave.
// Returns pointer to departing Train.
Train* leave ()
{
while (getTrainPtr() == NULL)
{
std::cout << "No train at " << getName() <<
"!\n";
usleep(10 + rand() % 10);
}
Train* toReturn = getTrainPtr();
std::cout << toReturn->getName() << " leaving " << getName() << "\n";
usleep(10 + rand() % 10);
trainPtr_ = NULL;
return(toReturn);
}
};
/*-------------------------------------------------------------------------*
*---
---*
*--- trainLine.cpp
---*
*---
---*
*--- This file defines code the implements 2 Station
instances, ---*
*--- and some number of Train objects that transit
between them. ---*
*---
---*
*--- ---- ---- ----
---- ---- ---- ----
---- ---*
*---
---*
*---
---*
*-------------------------------------------------------------------------*/
// Compile with: $ g++ trainLine.cpp -o trainLine -lpthread -g
#include <cstdlib>
#include <string>
#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include "Train.h"
#include "Station.h"
const int NUM_TRAINS
= 4;
const int NUM_NORTHERNLY_TRAINS =
NUM_TRAINS / 2;
const int NUM_SOUTHERNLY_TRAINS =
NUM_TRAINS - NUM_NORTHERNLY_TRAINS;
const int NUM_LOOPS = 16;
const char* TRAIN_NAME_ARRAY[NUM_TRAINS]
= { "Thomas the
Tank-Engine",
"Engine No. 9",
"California Zephyr",
"Tokaido Shinkansen"
};
const int TRAIN_TRANSIT_TIME_MSECS[NUM_TRAINS]
= { 10000, //
Thomas
10000, // Engine
no. 9
5000, // CA
Zephyr
1000 // Bullet
train
};
Station northTerminal("North
Station");
Station southTerminal("South
Station");
// PURPOSE: To make the Train object pointed to by 'vPtr' do
'NUM_LOOP' times:
// * arrive at 'northTerminal'
// * leave at 'northTerminal'
// * pause
// * arrive at 'southTerminal'
// * leave at 'southTerminal'
// * pause
// Returns a pointer to the Train it used.
void* initiallyNorthernly (void* vPtr)
{
// YOUR CODE HERE
}
// PURPOSE: To make the Train object pointed to by 'vPtr' do
'NUM_LOOP' times:
// * arrive at 'southTerminal'
// * leave at 'southTerminal'
// * pause
// * arrive at 'northTerminal'
// * leave at 'northTerminal'
// * pause
// Returns a pointer to the Train it used.
void* initiallySouthernly (void* vPtr)
{
// YOUR CODE HERE
}
int main (int argc,
char*
argv[]
)
{
if (argc > 1)
srand(strtol(argv[1],NULL,10));
pthread_t tidArray[NUM_TRAINS];
Train* trainArray[NUM_TRAINS];
for (int i = 0; i < NUM_TRAINS; i++)
trainArray[i] = new
Train(TRAIN_NAME_ARRAY[i],TRAIN_TRANSIT_TIME_MSECS[i]);
int trainInd = 0;
// Please make 'NUM_NORTHERNLY_TRAINS' threads (tidArray[0]
to
// tidArray[NUM_NORTHERNLY_TRAINS-1]) run
'initiallyNorthernly()'.
// Each thread should get a pointer to its own Train instance
// (trainArray[0] to trainArray[NUM_NORTHERNLY_TRAINS-1], this
is
// an array of POINTERS to trains, not trains themselves).
for (trainInd = 0; trainInd < NUM_NORTHERNLY_TRAINS;
trainInd++)
// YOUR CODE HERE
// Please make 'NUM_SOUTHERNLY_TRAINS' threads
// (tidArray[NUM_NORTHERNLY_TRAINS] to tidArray[NUM_TRAINS-1])
run
// 'initiallySouthernly()'. Each thread should get a pointer to its
own
// Train instance (trainArray[NUM_NORTHERNLY_TRAINS] to
// trainArray[NUM_TRAINS-1], this is an array of POINTERS to
trains, not
// trains themselves).
for ( ; trainInd < NUM_TRAINS; trainInd++)
// YOUR CODE HERE
// Leave this loop here. I want to make sure you get the Train
pointers
// back from initiallyNorthernly and initiallySouthernly().
for (int i = 0; i < NUM_TRAINS; i++)
trainArray[i] = NULL;
// Wait for all Train threads. Also, get the pointers to the
Train objects
// and delete() them because they were created by 'new'
// YOUR CODE HERE
return(EXIT_SUCCESS);
}
We need at least 10 more requests to produce the answer.
0 / 10 have requested this problem solution
The more requests, the faster the answer.
Please fill in the YOUR CODE HERE blocks for trainLine.cpp and provide a sample output. The...
I need help modifying this code please ASAP using C++ Here is what I missed on this code below Here are the instructions Here is the code Produce correct70 pts O pts Full Marks No Marks results and statisfy requirements view longer Comments 1. Your display amount is not readable 2. I withdraw more than my balance, but I didn't see any error message description Documentations10 pts 0 pts Full Marks No Marks : comment i code and block comment...