98 lines
2.5 KiB
C++
98 lines
2.5 KiB
C++
#include <condition_variable>
|
|
#include <cstdint>
|
|
#include <exception>
|
|
#include <iostream>
|
|
#include <mutex>
|
|
#include <string>
|
|
#include <thread>
|
|
#include <vector>
|
|
|
|
std::mutex mutex;
|
|
std::condition_variable condition_variable;
|
|
bool goose_working = true;
|
|
bool humpty_working = true;
|
|
uint32_t turn = 0;
|
|
|
|
class out_of_ink_exception : public std::exception { };
|
|
|
|
class Printer {
|
|
public:
|
|
Printer(const std::string& name, const uint32_t& client_ink_level)
|
|
: name(name), client_ink_level(client_ink_level) { }
|
|
|
|
bool operator==(const Printer& other) const {
|
|
return name == other.name;
|
|
}
|
|
|
|
std::string name;
|
|
uint32_t client_ink_level;
|
|
};
|
|
|
|
Printer reserve("Reserve", 5);
|
|
Printer primary("Primary", 5);
|
|
Printer printer = primary;
|
|
|
|
void display(const std::string& text) {
|
|
if ( printer == primary && printer.client_ink_level == 0 ) {
|
|
printer = reserve;
|
|
}
|
|
|
|
if ( printer.client_ink_level > 0 ) {
|
|
printer.client_ink_level--;
|
|
std::cout << "(" + printer.name + ") " + text << std::endl;
|
|
} else {
|
|
std::cout << " Printer out of ink" << std::endl;
|
|
throw out_of_ink_exception();
|
|
}
|
|
}
|
|
|
|
auto messenger =
|
|
[](const std::vector<std::string>& message, const uint32_t& my_turn, const uint32_t& turn_count) {
|
|
std::unique_lock<std::mutex> lock(mutex);
|
|
uint64_t index = 0;
|
|
while ( goose_working || humpty_working ) {
|
|
condition_variable.wait(lock, [&]() { return turn % turn_count == my_turn; });
|
|
|
|
if ( index < message.size() ) {
|
|
try {
|
|
display(message[index++]);
|
|
} catch (const out_of_ink_exception& ex) {
|
|
goose_working = false;
|
|
humpty_working = false;
|
|
}
|
|
} else {
|
|
if ( my_turn == 0 ) {
|
|
goose_working = false;
|
|
} else {
|
|
humpty_working = false;
|
|
}
|
|
}
|
|
|
|
turn++;
|
|
condition_variable.notify_one();
|
|
}
|
|
|
|
};
|
|
|
|
int main() {
|
|
const std::vector<std::string> goose_text = { "Old Mother Goose,",
|
|
"When she wanted to wander,",
|
|
"Would ride through the air,",
|
|
"On a very fine gander.",
|
|
"Jack's mother came in,",
|
|
"And caught the goose soon,",
|
|
"And mounting its back,",
|
|
"Flew up to the moon." };
|
|
|
|
const std::vector<std::string> humpty_text = { "Humpty Dumpty sat on a wall.",
|
|
"Humpty Dumpty had a great fall.",
|
|
"All the king's horses and all the king's men,",
|
|
"Couldn't put Humpty together again." };
|
|
|
|
std::thread goose_thread(messenger, goose_text, 0, 2);
|
|
std::thread humpty_thread(messenger, humpty_text, 1, 2);
|
|
|
|
goose_thread.join();
|
|
humpty_thread.join();
|
|
}
|