Найшов завдання цікаве про шлюбки, але не можу виканоти... Як можна створити потоки в циклі, щоб програма вічно працювала?
#include <string>
struct node;
class boat {
private:
struct node* mass;
std::string name;
int load;
public:
void addboat();
node** returnfst();
int returnload();
std::string returnname();
void addmass(class boat, struct node**);
void newnass(struct node**);
};
struct node {
struct node* next;
class boat bt;
};
#pragma once
#include "boat.h"
class tunnel :public boat{
private:
struct node* first;
public:
void addline(struct node*,struct node**);
node** returntun();
void newtunnel(struct node**);
};
#pragma once
#include"tunnel.h"
#include "boat.h"
class bearth : public tunnel{
public:
std::string name;
void cleanboat(node*);
void addname(std::string);
std::string returnst();
};
#include "bearth.h"
#include <iostream>
#include <chrono>
#include <mutex>
#include <thread>
#include "boat.h"
void bearth::cleanboat(node* tunnel) {
node* full = tunnel;
if (returnst() == full->bt.returnname()) {
if (full->bt.returnload() == 10) {
std::this_thread::sleep_for(std::chrono::milliseconds(250));
std::cout << "Корабель із " << full->bt.returnname() << "-ом розгружено на причалі " << returnst() << " за 1 хвилину." <<std::endl;
}
else {
if (full->bt.returnload() == 50) {
std::this_thread::sleep_for(std::chrono::milliseconds(1250));
std::cout << "Корабель із " << full->bt.returnname() << "-ом розгружено на причалі " << returnst() << " за 5 хвилину." << std::endl;
}
else {
if (full->bt.returnload() == 100) {
std::this_thread::sleep_for(std::chrono::milliseconds(2500));
std::cout << "Корабель із " << full->bt.returnname() << "-ом розгружено на причалі " << returnst() << " за 10 хвилин." << std::endl;
}
}
}
}
else {
if (returnst() == full->bt.returnname()) {
if (full->bt.returnload() == 10) {
std::this_thread::sleep_for(std::chrono::milliseconds(250));
std::cout << "Корабель із " << full->bt.returnname() << "-ом розгружено на причалі " << returnst() << " за 1 хвилину."<< std::endl;
}
else {
if (full->bt.returnload() == 50) {
std::this_thread::sleep_for(std::chrono::milliseconds(1250));
std::cout << "Корабель із " << full->bt.returnname() << "-ом розгружено на причалі " << returnst() << " за 5 хвилин." << std::endl;
}
else {
if (full->bt.returnload() == 100) {
std::this_thread::sleep_for(std::chrono::milliseconds(2500));
std::cout << "Корабель із " << full->bt.returnname() << "-ом розгружено на причалі " << returnst() << " за 10 хвилин." << std::endl;
}
}
}
}else{
if (returnst() == full->bt.returnname()) {
if (full->bt.returnload() == 10) {
std::this_thread::sleep_for(std::chrono::milliseconds(250));
std::cout << "Корабель із " << full->bt.returnname() << "-ом розгружено на причалі " << returnst() <<" за 1 хвилину."<< std::endl;
}
else {
if (full->bt.returnload() == 50) {
std::this_thread::sleep_for(std::chrono::milliseconds(1250));
std::cout << "Корабель із " << full->bt.returnname() << "-ом розгружено на причалі " << returnst() << " за 5 хвилин." << std::endl;
}
else {
if (full->bt.returnload() == 100) {
std::this_thread::sleep_for(std::chrono::milliseconds(2500));
std::cout << "Корабель із " << full->bt.returnname() << "-ом розгружено на причалі " << returnst() << " за 10 хвилин." << std::endl;
}
}
}
}
}
}
}
void bearth::addname(std::string na) {
name = na;
}
std::string bearth::returnst() {
return name;
}
#include "tunnel.h"
#include "boat.h"
void tunnel::addline(struct node* boat,struct node**fst) {
if ((*fst) == nullptr) {
(*fst) = new node;
(*fst)->bt = boat->bt;
(*fst)->next = nullptr;
}
else {
struct node* last = (*fst);
while (last->next != nullptr) {
last = last->next;
}
last->next = new node;
last = last->next;
last->bt = boat->bt;
last->next = nullptr;
}
}
node** tunnel::returntun() {
return &first;
}
void tunnel::newtunnel(struct node** nt) {
first = (*nt)->next;
}
#include "boat.h"
#include <iostream>
void boat::addboat(){
int nm = rand()%3;
int waight = rand() % 3;
if (nm == 0) {
if (waight == 0) {
name = "Хліб";
load = 10;
}
else {
if (waight == 1) {
name = "Хліб";
load = 50;
}
else {
if (waight == 2) {
name = "Хліб";
load = 100;
}
}
}
}
else {
if (nm == 1) {
if (waight == 0) {
name = "Банан";
load = 10;
}
else {
if (waight == 1) {
name = "Банан";
load = 50;
}
else {
if (waight == 2) {
name = "Банан";
load = 100;
}
}
}
}
else {
if (nm == 2) {
if (waight == 0) {
name = "Одяг";
load = 10;
}
else {
if (waight == 1) {
name = "Одяг";
load = 50;
}
else {
if (waight == 2) {
name = "Одяг";
load = 100;
}
}
}
}
}
}
}
int boat::returnload() {
return load;
}
std::string boat::returnname() {
return name;
}
void boat::addmass(class boat boat, struct node** fst) {
if ((*fst) == nullptr) {
(*fst) = new node;
(*fst)->bt = boat;
(*fst)->next = nullptr;
}
else {
struct node* last = (*fst);
while (last->next != nullptr) {
last = last->next;
}
last->next = new node;
last = last->next;
last->bt = boat;
last->next = nullptr;
}
}
node** boat::returnfst() {
return &mass;
}
void boat::newnass(struct node** nnode) {
mass = (*nnode)->next;
}
#include <iostream>
#include <chrono>
#include <mutex>
#include <thread>
#include "boat.h"
#include "tunnel.h"
#include "bearth.h"
std::mutex mx1;
std::mutex mx2;
std::mutex mx3;
int main(void) {
setlocale(LC_ALL, "");
boat mass;
tunnel line;
bearth bana;
bearth clothe;
bearth bre;
bana.addname("Банан");
clothe.addname("Одяг");
bre.addname("Хліб");
node* ma;
auto fu1 = [&mass]() {
mx1.lock();
boat newb;
newb.addboat();
newb.addmass(newb, (mass.returnfst()));
std::cout << "Шлюбку додано." << std::endl;
mx1.unlock();
};
auto fu2 = [&line,&mass]() {
mx1.lock();
mx2.lock();
line.addline(*mass.returnfst(), line.returntun());
mass.newnass(mass.returnfst());
std::cout << "Шлюбку додано в тунель." << std::endl;
mx2.unlock();
mx1.unlock();
};
auto fu3 = [&bre,&bana,&clothe,&line]() {
mx2.lock();
mx3.lock();
bre.cleanboat(*line.returntun());
bana.cleanboat(*line.returntun());
clothe.cleanboat(*line.returntun());
line.newtunnel(line.returntun());
mx3.unlock();
mx2.unlock();
};
std::thread td1(fu1);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
std::thread td2(fu2);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
std::thread td3(fu3);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
std::thread td4(fu1);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
std::thread td5(fu2);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
std::thread td6(fu3);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
std::thread td7(fu1);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
std::thread td8(fu2);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
std::thread td9(fu3);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
td9.join();
td8.join();
td7.join();
td6.join();
td5.join();
td4.join();
td3.join();
td2.join();
td1.join();
return 0;
}
Ось завдання :
Задание было следующее:
Есть транспортные корабли, которые подплывают к туннели и далее плывут к причалам для погрузки разного рода товара.
Они проходят через узкий туннель где одновременно могут находиться только 5 кораблей. Под словом “подплывают к туннели” имеется ввиду то, что корабли должны откуда-то появляться. Их может быть ограниченное количество, то есть 10 или 100, а может быть бесконечное множество. Слово “Подплывают” назовем генератором кораблей.
Вид кораблей и их вместительность могут быть разными в зависимости от типа товаров, которые нужно загрузить на корабль. То есть для ТЗ я придумал 3 Типа кораблей (Хлеб, Банан и Одежда) и три вида вместительности 10, 50, 100 шт. товаров. 3 типа кораблей * 3 вида вместительности = 9 разных видов кораблей.
Далее есть 3 вида причалов для погрузки кораблей — Хлеб, Банан и Одежда. Каждый причал берет или подзывает к себе необходимый ему корабль и начинает его загружать. За одну секунду причал загружает на корабль 10 ед. товара. То есть если у корабля вместительность 50 шт., то причал загрузит его за 5 секунд своей работы.
Требование было следующее:
Правильно разбить задачу на параллельность.
Синхронизировать потоки, сохранить целостность данных. Ведь ограничить доступ потоков к общему ресурсу дело не сложное, а заставить их работать согласованно уже намного сложнее.
Работа генератора кораблей не должна зависеть от работы причалов и наоборот.
Общий ресурс должен быть Thread Safe (Если таковой есть в реализации)
Потоки не должны быть активными если нет задач.
Потоки не должны держать mutex если нет задач.