Like in my title, my goal is to use the producer consumer model to mimic the linux cat command(ouput the contents of the file to screen). When I try running the program using lab3 5 animals.txt (lab3 the compiled/renamed executable, 5 being the size of the bounded buffer, and test_alarm.cpp being the name of the file to be printed), lines in the ouput seem to have been outputted multiple times. I am not sure what could be causing this(maybe I am not deleting the contents of the buffer properly? Though I'm not sure why that would cause multiple prints), so any help is appreciated.
An oddpoint is when I change the positions of 'ifstream infile' from global to the producer func, the output seems to change as well.
Animals.txt (output using linux's 'cat')
I have a dog
Dogs are large
I also have a cat
Animals.txt (output using my program)
I have a dog
Dogs are large
I also have a cat
I have a dog
Dogs are large
I also have a cat
I have a dog
Dogs are large
I have a dog
(Latest output)
counter in prod is: 1
counter in prod is: 2
counter in prod is: 3
I have a dog
counter in consumer is: 3
Dogs are large
counter in consumer is: 2
Segmentation fault (core dumped)
code
#include <iostream>
#include <string>
#include <semaphore.h>
#include <fstream>
#include <unistd.h>
#include <mutex>
#include <condition_variable>
#include <thread>
using namespace std;
int counter = 0; //number of words in buffer
int buffmax; //size of buffer
string filename;
mutex mu;
condition_variable cond;
string* buffer;
bool flag = false;
ifstream infile;
void produce()
{
infile.open(filename);
while(getline(infile, temp)) //!infile.eof()
{
unique_lock<mutex> locker(mu);
cond.wait(locker, []() {return counter < buffmax; }); //if true then produce, if false then wait
buffer[counter] = temp;
//infile >> buffer[counter];
counter++;
//cout << "counter in prod is: " << counter << endl;
locker.unlock();
cond.notify_one(); //notify consumer thread
}
infile.close();
flag = true;
}
void consume()
{
while(true)
{
if (flag == true && counter <= 0)
break;
unique_lock<mutex> locker(mu);
cond.wait(locker, []() {return counter > 0; });
cout << buffer[0] << endl;
string *x = new string[buffmax];
for(int i = 0; i < counter-1; i++) // reason for seg fault?
{
x[i]=buffer[i+1];
}
delete [] buffer;
buffer = NULL
buffer = x;
x = NULL;
//cout << "counter in consumer is: " << counter << endl;
counter--;
locker.unlock();
cond.notify_one(); //notify producer thread
}
}
int main(int argc, char* argv[])
{
string s = argv[1];
buffmax = stoi(s); //size of the buffer
filename = string(argv[2]); // name of file to be parsed
buffer = new string[buffmax]; // creating the bounded buffer
thread t1(produce);
thread t2(consume);
t1.join();
t2.join();
return 0;
}