! [Railroad]: http://www.cs.tut.fi/~rinn/htyo/design/pics/railroad.png
Я пытаюсь создать программное обеспечение для моделирования поездов, едущих по железной дороге, как показано выше.Проблемы параллелизма проистекают из следующих граничных условий:
* Каждый участок пути является ОДНЫМ ВРЕМЯ за один раз: когда поезд начинает идти в одном направлении, не может быть никаких других поездов, идущих в противоположном направлении (примечание: это позволяет использовать несколько поездов в одном и том же направлении).
* Когда поезд начался на участке, он ДОЛЖЕН перейти к следующему участку / перекрестку (другими словами: в середине участка пути нет разворота)
* Поезда НЕ должны иметь определенного расписания (их общее движение может быть случайным во всей сети треков).
* Места обмена / переключения путей могут быть «волшебными» вощущение, что любое количество поездов может находиться на них (в ожидании), все поезда могут проходить друг в друга в любом направлении внутри них.
Мой план состоял бы в том, чтобы создать 2 переменные, одна из которых содержала бы текущее направление движения поездов на пути, а вторая - подсчет количества поездов на пути.Идея состоит в том, чтобы сначала проверить, разрешено ли поезду входить на путь (другими словами, направление на пути == направление отходящего поезда ИЛИ, если путь пуст), а затем увеличить количество поездов на пути.Когда последний поезд на пути прибудет к следующему перекрестку, переменная направления будет установлена на 0, что позволит любым поездам получать доступ к пути.
Насколько я могу судить, мне нужно было бы создать свойсвой собственный механизм блокировки, чтобы реализовать это, но я заблудился в специфике реализации.Кажется, что переменные условия могут быть полезны, но все советы, которые я читал, используют мьютекс, что не подходит для нашего случая.Может быть, семпахор с условной переменной?
В случае, если это полезно, вот реализация до сих пор: railroad.cc
#include <chrono>
#include <thread>
#include <iostream>
#include <mutex>
#include <atomic>
#include "railroad.hh"
std::atomic_int lock = 0;
std::mutex cout_mutex;
Railroad::Railroad(std::vector<Track> tracks, std::vector<int> junctions, std::vector<Train> trains):
tracks(tracks), junctions(junctions), trains(trains)
{
}
bool Railroad::moveTrain(int id)
{
for(int i = 0; i < 10; i++){
std::this_thread::sleep_for(std::chrono::milliseconds(std::rand()%300));
bool finished = false;
int target_id = rand()%6;
int start;
for(auto train_it = trains.begin(); train_it != trains.end(); train_it++){
if(finished){
break;
}
if(train_it->getId() == id){
start = train_it->getLocation();
train_it->setMoving(true);
for(auto track_it = tracks.begin(); track_it != tracks.end(); track_it++){
if(track_it->id == target_id){
finished = true;
if(start == track_it->point2){
track_it->in_use == true;
cout_mutex.lock();
std::cout << "Train " << id
<< " started moving on track "
<< target_id << std::endl;
cout_mutex.unlock();
std::this_thread::sleep_for(std::chrono::milliseconds(std::rand()%1000));
train_it->setLocation(track_it->point1);
train_it->setMoving(false);
cout_mutex.lock();
std::cout<< "Train " << id << " has arrived from "
<< start << " to " << track_it->point1
<<std::endl;
cout_mutex.unlock();
break;
}
else if(start == track_it->point1){
track_it->in_use == true;
cout_mutex.lock();
std::cout << "Train " << id << " started moving on track "
<< target_id << std::endl;
cout_mutex.unlock();
std::this_thread::sleep_for(std::chrono::milliseconds(std::rand()%1000));
train_it->setLocation(track_it->point2);
train_it->setMoving(false);
cout_mutex.lock();
std::cout<< "Train " << id << " has arrived from " << track_it->point1 << " to " << track_it->point2 <<std::endl;
cout_mutex.unlock();
break;
}
else{
cout_mutex.lock();
std::cout<< "Train " << id << " cannot access "<<track_it->id << std::endl;
cout_mutex.unlock();
break;
}
}
}
}
}
}
}
main.cpp
#include <iostream>
#include <memory>
#include <random>
#include <thread>
#include "railroad.hh"
using namespace std;
int main()
{
std::vector<Track> tracks;
tracks.push_back({0,0,2, false});
tracks.push_back({1, 2, 3, false});
tracks.push_back({2, 3, 0, false});
tracks.push_back({3, 0, 1, false});
tracks.push_back({4, 1, 2, false});
tracks.push_back({5, 1, 3, false});
std::vector<int> junctions;
std::vector<Train> trains;
trains.push_back({0,0,false});
trains.push_back({1,1,false});
trains.push_back({2,2,false});
junctions.push_back(0);
junctions.push_back(1);
junctions.push_back(2);
junctions.push_back(3);
Railroad* railroad = new Railroad(tracks, junctions, trains);
std::thread t1(&Railroad::moveTrain,railroad,0);
std::thread t2(&Railroad::moveTrain,railroad,1);
std::thread t3(&Railroad::moveTrain,railroad,2);
t1.join();
t2.join();
t3.join();
}