混乱使用线程和线程技术

时间:2012-10-15 00:51:27

标签: c++ multithreading

有一个建筑区。 100米长的汽车驶向东/西...... 10米跨越行人穿越N / S.以下是必须遵循的规则:

如果交叉路口是空的,汽车和行人都不应该等待; 在单车道区域,汽车不能同时向相反方向行驶; 如果单行车道上有车,行人不能过马路,但是 多个行人可以同时过马路; 如果有一辆车朝同一方向行驶,汽车可以进入单车道段,但是,不允许汽车通过另一辆车; 一辆汽车不会等待两辆以上的汽车朝相反方向行驶; 一个行人必须屈服于汽车但是行人不应该等待超过两辆汽车(向任何一个方向)。

使用的示例文件如下:(每行是一个单独的实体.E表示“汽车往东走”,W表示西.P表示行人。第一列是前一个实体到达后的秒数现在新实体到了。第三列是速度(米/秒): 正在使用的例子:

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

1 个答案:

答案 0 :(得分: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名行人。因此e将为2,而pw将为1. crosser[0]是一辆东方汽车

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

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