0

建設ゾーンがあります。東西に向かう車の場合は長さ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));
}
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 人います。だからe2になり、pそしてw1になります。 crosser[0]は東の車です

次に、これらの push_back ループを見てください。crossers[0] をすべてのリストに追加しています! したがって、最初の (そして唯一の)westCar車両は、実際には東側の車両です。しかし、あなたcarWestは西側の車以外での作業を拒否するため、機能しません。

全員を 1 つのリストに入れるのではなく、完全に個別のリストを維持したいでしょうcrossers。それか、crossersリストを1回ループし、を調べて、nameそれがどのリスト/スレッドに入るかを確認できます。

于 2012-10-15T02:33:08.387 に答える