有施工区。100m 长,用于向东/向西行驶的汽车....10m 用于穿过 N/S 的行人。以下是必须遵守的规则:
如果十字路口是空的,汽车和行人都不应等待;在单车道路段,汽车不能同时向相反方向行驶;单车道路段有车时,一个行人不能过马路,但多个行人可以同时过马路;同一车道路段如果有同方向行驶的汽车,汽车可以进入,但不允许汽车超车;一辆汽车不会等待超过两辆汽车朝相反方向行驶;行人必须让车,但行人不应等待超过两辆汽车(在任一方向)。
正在使用的示例文件如下:(每一行是一个单独的实体。E 表示“汽车向东行驶”,W 表示向西。P 表示行人。第一列是前一个实体到达后的秒数,现在新实体正在到达。第三列是速度(米/秒):正在使用的示例:
0 E1 10
1 P1 1
4 E2 15
5 W1 10
目前我的代码正在打印出 E1 enters.... (下一行) E1 exits.... 这不断重复。我对使用线程和包含的技术很困惑,所以此刻我被困住了。我需要更改什么才能打印出实体应该到达和离开施工区的正确顺序?感谢所有帮助。
#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));
}