70 lines
2.9 KiB
C++
70 lines
2.9 KiB
C++
#include <iostream>
|
|
#include <memory>
|
|
#include <list>
|
|
#include <string>
|
|
#include <thread>
|
|
#include <cstdio>
|
|
#include <random>
|
|
#include <philosopher.hpp>
|
|
|
|
class Philosopher;
|
|
|
|
void
|
|
findNumberOfPhilosophersInParams(const int argc, char **argv, int *const numberOfPhilosophers);
|
|
|
|
int
|
|
main(int argc, char **argv) {
|
|
// std::shared_ptr<std::vector<std::shared_ptr<Philosopher>>
|
|
ListOfPhilosophersPtr philosophers(new ListOfPhilosophers());
|
|
// Default value for the number of dining philosophers.
|
|
int numberOfPhilosophers = 5;
|
|
// Attempts to find a tailored value provided by the user for numberOfPhilosophers.
|
|
findNumberOfPhilosophersInParams(argc, argv, &numberOfPhilosophers);
|
|
printf("%d philosophers to create.\n", numberOfPhilosophers);
|
|
// Pushes a number of philosophers equal to numberOfPhilosophers to the table.
|
|
for (int i = 0; i < numberOfPhilosophers; i++) {
|
|
printf("Creating philosopher: %d.\n", i);
|
|
philosophers->push_back(PhilosopherPtr(new Philosopher(philosophers, i)));
|
|
}
|
|
// If the jthreads go out of scope is equal than joining, which is undersirable on the
|
|
// insides of a for loop if we want they to execute in parallel.
|
|
std::vector<std::jthread> threads;
|
|
for (unsigned long int i = 0; i < philosophers->size(); i++) {
|
|
// A pitfall would be to use here i directly since it would be incremented before
|
|
// it is used by jthread, so a pointer is needed.
|
|
std::shared_ptr<unsigned long> numberOfPhilosopher(new unsigned long());
|
|
*numberOfPhilosopher = i;
|
|
threads.push_back(std::jthread([philosophers, numberOfPhilosopher] {
|
|
// This starts the dinner for the philosopher *numberOfPhilosopher.
|
|
// While philosophers are yet not dinning the state for them is thinking
|
|
// anyway, so they have to problem with the neighbors dining already.
|
|
(*philosophers)[*numberOfPhilosopher]->startThread();
|
|
} ));
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Checks if the parameter list is greater or equal than 2 and takes the second parameter.-
|
|
* The first if ignoring the current executable name.- And with this parameter attempts to
|
|
* get a number to be used as the number of philosophers in the table.
|
|
*
|
|
* In case of failure, numberOfPhilosophers is not changed, else is set to the integer value
|
|
* of the parameter.
|
|
*/
|
|
void
|
|
findNumberOfPhilosophersInParams(const int argc, char **argv, int *const numberOfPhilosophers) {
|
|
// The user did not gave us enough arguments, early return.
|
|
if (argc < 2) {
|
|
return;
|
|
}
|
|
// numberOfPhilosophersAsString is now equal to the supposed number the user gave us.
|
|
const char *numberOfPhilosophersAsString = argv[1];
|
|
try {
|
|
// Converts param to number, can throw an exception.
|
|
*numberOfPhilosophers = std::stoi(numberOfPhilosophersAsString, NULL, 10);
|
|
} catch (std::exception &ex) {
|
|
printf("The number of philosophers is not a valid number, continuing\n");
|
|
}
|
|
}
|
|
|