0

I am trying to create a tunnel and car threads that simulate a tunnel that only goes one way. Lets say each way is W and B. The way to W is open for 5 seconds, then the tunnel is closed for another 5, then the tunnel is open for way B for 5 seconds and then closed for another 5, then repeat.

I have created the tunnel thread with the tunnelf function but it does not do anything but print the first line: "The tunnel is now open to Whittier Bound traffic". And it only does that sometimes. Each time i compile the code, it can either print nothing or that line. It does not go through the required outputs. Meanwhile if i put the exact same while loop from the tunnelf thread into main, it works

#include <iostream>
#include <cstring>
#include <string>
#include <cctype>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <pthread.h>
#include <conio.h>
#include <windows.h>
#include <ctime>
#include <cerrno>
#include <unistd.h>
using namespace std;
void *car(void *arg);
void *tunnelf();
static pthread_mutex_t traffic_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t car_lock = PTHREAD_MUTEX_INITIALIZER;

static pthread_cond_t bbcan = PTHREAD_COND_INITIALIZER;
static pthread_cond_t wbcan =PTHREAD_COND_INITIALIZER;
static pthread_cond_t not_full = PTHREAD_COND_INITIALIZER;
static bool whittierBound = false;
static bool bbBound = false;

struct car2{
    int arrive;
    int cross;
    string bound;
};

int main(){
    ifstream in;
    in.open("Thrd.txt");
    if (in.fail()){
        cout<< "failed to open file";
        exit(1);
    }
    car2 record[50];
    int max_cars;
    int arrive;
    int cross;
    string bound;
    string data;
    int i = 0;
    in >> max_cars;
    cout<<"Num cars "<<max_cars<<endl;
    while(!in.eof()){
        in >> record[i].arrive >>record[i].bound >> record[i].cross;
        i++;
    }
    int size = i;
    for(int i= 0; i<size; i++){
        cout << record[i].arrive <<record[i].bound <<record[i].cross<<endl;
    }
    pthread_t cartid[max_cars];
    pthread_t tunnel;//just shared variable for the tunnel
    pthread_create(&tunnel, NULL, &tunnelf, NULL);
    in.close();
}

void *tunnelf(){
    static int done;
    while(done==0){
        pthread_mutex_lock(&traffic_lock);
        whittierBound = true;

        cout << "The tunnel is now open to Whiitier-bound traffic"<<endl;
        pthread_cond_broadcast(&wbcan);
        pthread_mutex_unlock(&traffic_lock);
        sleep(5);

        pthread_mutex_lock(&traffic_lock);
        whittierBound = false;
        cout << "The tunnel is now closed to all traffic"<<endl;
        pthread_mutex_unlock(&traffic_lock);
        sleep(5);

        pthread_mutex_lock(&traffic_lock);
        bbBound = true;
        cout << "The tunnel is now open to Bear-Valley-bound traffic"<<endl;
        pthread_cond_broadcast(&bbcan);
        pthread_mutex_unlock(&traffic_lock);
        sleep(5);

        pthread_mutex_lock(&traffic_lock);
        bbBound = false;
        cout << "The tunnel is now closed to all traffic"<<endl;
        pthread_mutex_unlock(&traffic_lock);

    }   
}
Dees
  • 45
  • 1
  • 7
  • Not that it helps with this but C++ [now has thread support built in](http://en.cppreference.com/w/cpp/header/thread). It makes threading a lot easier to deal with then dealing with `pthread` – NathanOliver Apr 20 '18 at 20:38
  • Also, don't use [`while(!in.eof())` to read a file](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – NathanOliver Apr 20 '18 at 20:39
  • Also, initialize `done` – greedy52 Apr 20 '18 at 20:42
  • @greedy It's static, it's initialised to zero. –  Apr 20 '18 at 20:43
  • @NathanOliver its an assignment. I am required to use pthreads – Dees Apr 20 '18 at 20:46
  • @NathanOliver what am i to use if not eof? – Dees Apr 20 '18 at 20:48
  • anyone have any idea what the problem is? – Dees Apr 20 '18 at 20:48
  • @Dees The TL;DR of the link I gave you is `while (in >> record[i].arrive >>record[i].bound >> record[i].cross)` – NathanOliver Apr 20 '18 at 20:48
  • You need to post the output of program, because "does not do anything but print the first line" is ambiguous. Do you mean the first line of main, e.g. "Num cars", or the first line of tunnel, e.g. "The tunnel is now open to Whiitier-bound traffic"??? – Tiger4Hire Apr 20 '18 at 21:04
  • @Tiger4Hire i have done it – Dees Apr 20 '18 at 21:10
  • That helps. Do you also have a cut-down version of the car function? It could be doing anything. Also, there are several things worth tidying, You have multiple definitions of the bbcan,wbcan,notfull condition variables. It looks harmless, but it makes the code more confusing. Also you should guard against too many lines in the data file.... I'll post an example fix in an answer – Tiger4Hire Apr 20 '18 at 21:22
  • @Tiger4Hire what do you mean by cut down? You want me to remove it? – Dees Apr 20 '18 at 21:27
  • If it's small, nothing, If it's large, remove any commented out blocks, for example. The more you change it, the more chance you will comment out the problem, but you will get better/faster answers if the code is easy to read. Commented out code rarely helps readability. – Tiger4Hire Apr 20 '18 at 21:32
  • By the way, I think the reason you are not getting much traction is that your code (the bit your posting) looks fine, if a little old-fashioned, and a bit messy. Which is why I'm checking the code that might be missing. – Tiger4Hire Apr 20 '18 at 21:35
  • @Tiger4Hire I have edited the question code – Dees Apr 20 '18 at 21:38

1 Answers1

0

One thing to mention, you never guard against array overruns. In C++17, you can use std::size. You might consider using std::array for record, which would help in debug builds (but not release)

while(!in.eof() && i<std::size(record)){
    in >> record[i].arrive >>record[i].bound >> record[i].cross;
//      cout <<arrive<<" " << bound<<" " << cross<<endl;
    i++;
}
Tiger4Hire
  • 1,065
  • 5
  • 11
  • `!in.eof()` in the while loop repeats the legendary `while(!in.eof())` bug. It is best avoided. More on that here: https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong – user4581301 Apr 20 '18 at 21:58