建設ゾーンがあります。東西に向かう車の場合は長さ100m....N/Sを横断する歩行者の場合は横に10m。従わなければならないルールは次のとおりです。
交差点が空の場合、車も歩行者も待つべきではありません。1車線のセクションで車が同時に反対方向に進むことはできません。1車線区間に車がある間は歩行者は通りを横断できませんが、複数の歩行者が同時に通りを横断することはできます。同じ方向に進んでいる車がある場合、車は1車線セクションに入ることができますが、車が別の車を通過することは許可されていません。車は、2台以上の車が反対方向に進むのを待ちません。歩行者は車に屈する必要がありますが、歩行者は2台以上の車を(どちらの方向にも)待つべきではありません。
使用されているファイルの例は次のとおりです(各行は個別のエンティティです。Eは「東に向かう車」を意味し、Wは西になります。Pは歩行者用です。最初の列は、前のエンティティが到着してから現在までの秒数です。新しいエンティティが到着します。3番目の列は速度(メートル/秒)です。使用例:
0 E1 10
1 P1 1
4 E2 15
5 W1 10
現在、私のコードはE1入力を出力しています....(次の行)E1終了....これは何度も繰り返されます。私はスレッドと含まれているテクニックの使用についてかなり混乱しているので、現時点では行き詰まっています。エンティティが建設ゾーンに到着および出発する正しい順序を印刷するために、これを取得するには何を変更する必要がありますか?すべての助けに感謝します。
#include <iostream>
#include <vector>
#include <fstream>
#include <chrono>
#include <thread>
#include <random>
#include <ctime>
#include <mutex>
#include <string>
#include <condition_variable>
using namespace std;
class Traffic{
public:
void set_time(int a) {prevArrival = a;}
void set_name(string a) {name = a;}
void set_speed(int a) {carSpeed = a;}
int get_time() {return prevArrival;}
string get_name() {return name;}
int get_speed() {return carSpeed;}
private:
int prevArrival;
string name;
int carSpeed;
};
condition_variable_any cE, cW, ped;
mutex mtx;
int east=0; //number of cars traveling East currently in the zone
int west=0; //...traveling West...
int peds=0; //# of pedestrians crossing the street
void sleep(int secs);
void carWest(int time, string name, int speed);
void carEast(int time, string name, int speed);
void pedestrian(int time, string name, int speed);
int main(void){
srand(time(NULL));
ifstream ifs;
ofstream ofs;
string info, title, temp;
int i=0, e=0, w=0, p=0, time, speed;
Traffic crossers[50];
vector <thread> eastCars, westCars, pedestrians;
ifs.open("traffic.txt");
while (!ifs.eof()){
ifs >> time; crossers[i].set_time(time);
ifs >> title; crossers[i].set_name(title);
temp = crossers[i].get_name();
if(temp[0] == 'E' || temp[0] == 'e') {e++;}
else if(temp[0] == 'W' || temp[0] == 'w') {w++;}
else {p++;}
ifs >> speed; crossers[i].set_speed(speed);
i++;
}
ifs.close();
for (int i=0; i < e; i++) eastCars.push_back(thread(carEast, crossers[i].get_time(), crossers[i].get_name(), crossers[i].get_speed())); //creating threads
for (int i=0; i < p; i++) pedestrians.push_back(thread(pedestrian, crossers[i].get_time(), crossers[i].get_name(), crossers[i].get_speed()));
for (int i=0; i < w; i++) westCars.push_back(thread(carWest, crossers[i].get_time(), crossers[i].get_name(), crossers[i].get_speed()));
for (thread& t: eastCars) t.join(); // waiting for eastCars, westCars, and pedestrians to finish
for (thread& t: pedestrians) t.join();
for (thread& t: westCars) t.join();
}
void pedestrian(int time, string name, int speed) {
while(true){
if(name[0] == 'P' || name[0] == 'p'){
if(time == 0 || (east == 0 && west == 0 && peds == 0))
mtx.lock();
cout << name << " entering construction" << endl;
while(peds>0 || west>0 || east>0)
ped.wait(mtx);
peds++;
mtx.unlock();
sleep(10/speed);
cout << name << " exiting construction" << endl;
mtx.lock();
peds--;
ped.notify_one();
cE.notify_all();
cW.notify_all();
mtx.unlock();
}
}
}
void carWest(int time, string name, int speed) {
while(true){
if(name[0] == 'W' || name[0] == 'w'){
if(time == 0 || (east == 0 && west == 0 && peds == 0))
mtx.lock();
cout << name << " entering construction" << endl;
while(peds>0 || west>0 || east>0)
cW.wait(mtx);
west++;
mtx.unlock();
sleep(100/speed);
cout << name << " exiting construction" << endl;
mtx.lock();
west--;
cW.notify_one();
ped.notify_all();
cE.notify_all();
mtx.unlock();
}
}
}
void carEast(int time, string name, int speed) {
while(true){
if(name[0] == 'E' || name[0] == 'e'){
if(time == 0 || (east == 0 && west == 0 && peds == 0))
mtx.lock();
cout << name << " entering construction" << endl;
while(peds>0 || west>0 || east>0)
cE.wait(mtx);
east++;
mtx.unlock();
sleep(100/speed);
cout << name << " exiting construction" << endl;
mtx.lock();
east--;
cE.notify_one();
cW.notify_all();
ped.notify_all();
mtx.unlock();
}
}
}
void sleep(int secs){
this_thread::sleep_for(chrono::milliseconds(rand()%secs*1000));
}