2015-05-19 11 views
1

所以,我一直试图更好地理解条件变量是如何工作的,并且我编写了下面的代码来试图从相同的文本中实现读取和写入文件:代码不会提前通过条件变量的等待函数

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

而且,我模仿我的使用布尔变量以下example之后,从 cppreference.com(向下滚动到页面底部看到示例代码)。然而,它有一些我正在传递给wait函数的谓词,我不太确定它有什么问题。如果有人能够提供一些见解,这将是辉煌的。谢谢!

+0

你有一个[数据种族](http://en.cppreference.com/w/ cpp/language/memory_model)用'doneReading'和'doneWriting',因为它们被多个线程访问。请尝试使用['std :: atomic'](http://en.cppreference.com/w/cpp/atomic/atomic)。 – phantom

+2

@Phantom - 这里有一个数据竞赛,但没有这些变量。实施时,这些变量会造成死锁。数据竞赛是关于cout(混乱输出)和数据文件的。如果该文件尚不存在,则在'readFromFile'和'writeToFile'之间存在竞争。如果'readFromFile'赢得比赛,它会因为文件不存在而丢失。 –

回答

2

初始状态是:

bool doneReading=false; 
bool doneWriting=false; 

的第一件事readFromFile确实给这些变量是坐等doneWriting成为true

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

的第一件事writeFromFile确实给这些变量是坐着等待doneReading变成true

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

两种情况都不会成立。

注意,cppreference例子确实非常不同的东西:一个线程开始通过执行cv.wait(lk, []{return ready;});而另一方面开始通过执行ready=true;

相关问题