0

有施工区。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));
}
4

1 回答 1

0

你的问题在这里:

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()));

在您的小数据文件中,您有 2 辆东车、1 辆西车和 1 辆行人。So ewill be 2, pand wwill be 1. crosser[0]是东车

现在,看看那些 push_back 循环。您正在将 crossers[0] 添加到所有列表中!因此,您的第一辆(也是唯一一辆)westCar实际上是一辆东方汽车。但是你carWest拒绝做除了西车以外的任何工作,所以它不起作用。

您可能希望保留完全独立的列表,而不是将每个人都放在一个crossers列表中。或者你可以在你的crossers列表上循环一次,然后检查它name以查看它进入的列表/线程。

于 2012-10-15T02:33:08.387 回答