busebd12
busebd12

Reputation: 1007

Code won't advance past wait function for conditional variable

So, I've been trying to get a better understand of how condition variables work and I've written the following code that tries to implement reading and writing from the same text file:

    #include <iostream>
    #include <fstream>
    #include <cstdlib>
    #include <condition_variable>
    #include <mutex>
    #include <thread>

    using namespace std;

    mutex mtx;
    condition_variable conditionVariable;
    ifstream readFile;
    ofstream writeFile;
    bool doneReading=false;
    bool doneWriting=false;

    void readFromFile()
    {
        string line;

        readFile.open("./testFile.txt");

        if(readFile.is_open())
        {
            cout << "Successfully opened file!" << "\n";
        }
        else
        {
            cout << "Failed to open file..." << "\n";
        }

        cout << "The file contents are:" << "\n";
        while(getline(readFile,line))
        {
            unique_lock<mutex> lock(mtx);

            conditionVariable.wait(lock, [] () {return doneWriting;});

            cout << line << "\n";

            doneReading=true;

            lock.unlock();

            conditionVariable.notify_one();
        }
        readFile.close();
    }

    void writeToFile()
    {
        string input;

        writeFile.open("./testFile.txt");

        cout << "Enter something you want to write to the text file:" << "\n";
        cin >> input;
        cout << "Going to write " << input << " to the file" << "\n";

        if(writeFile.is_open())
        {
            cout << "Successfully opened file!" << "\n";

            unique_lock<mutex> lock2(mtx);

            /////////PROGRAM WON'T ADVANCE PAST THIS LINE/////////////
            conditionVariable.wait(lock2, [] () {return doneReading;}); 

            cout << "After calling the wait function for the condition variable" << "\n";

            writeFile << input;

            doneWriting=true;

            lock2.unlock();

            conditionVariable.notify_one();

            writeFile.close();
        }
        else
        {
            cout << "Failed to open file..." << "\n";
        }
    }


    int main()
    {

        int i;
        for(i=0;i<10;i++)
        {
            thread t1(readFromFile);
            thread t2(writeToFile);
            t1.join();
            t2.join();
        }
    }

And, I modeled my use of boolean variables after the following example from cppreference.com (scroll down to the bottom to see the example code). However, it has something do the predicate I am passing to the wait function, and I'm not quite sure what is wrong with it. If someone could give some insight, that would be brilliant. Thanks!

Upvotes: 1

Views: 96

Answers (1)

Cubbi
Cubbi

Reputation: 47418

Initial state is:

bool doneReading=false;
bool doneWriting=false;

The first thing readFromFile does to these variables is sit and wait for doneWriting to become true

conditionVariable.wait(lock, [] () {return doneWriting;});

The first thing writeFromFile does to these variables is sit and wait for doneReading to become true

conditionVariable.wait(lock2, [] () {return doneReading;}); 

Neither condition will become true.

Note that the cppreference example does something very different: one thread begins by executing cv.wait(lk, []{return ready;}); while the other begins by executing ready=true;

Upvotes: 2

Related Questions