【问题标题】:Reading in a file stream inside a thread function c++在线程函数c ++中读取文件流
【发布时间】:2017-02-28 16:34:06
【问题描述】:

我正在处理一个班级项目,但在让我的线程完全读取文件时遇到了麻烦。我可以让他们读完前两个单词,然后他们停下来不输出任何东西。在我的main 中,在我加入线程后,file.eof() 正在返回 true。有没有人对为什么会发生这种情况或如何解决它有任何建议?

(该项目是使用交替线程从文件中的短语中“排序”元音和辅音;我不能使用互斥锁,这就是为什么有一个转变量)

void cons(){
cout << "Turn is " << turn << endl; //outputs "Turn is 0"
    while (!file.eof()){
        if (turn == false){
            char c = word.at(0);
            if (c != 'A' || c != 'E' || c != 'I'|| c != 'O'|| c != 'U'){
                cout << "Consonant Thread: " << word << '\n';
                file >> word;
             }
    turn = true;
    }
    this_thread::yield();
    }
}

void vowel(){
    while (!file.eof()){
    if (turn == true){
        char c = word.at(0);
        if (c == 'A' || c == 'E' || c == 'I'|| c == 'O'|| c == 'U'){
        cout << "Vowel Thread: " << word << '\n';
        file >> word;
    }
    turn = false; //keeps track of thread turn to make sure the correct one is running
    }
    this_thread::yield();
    }
    }

上面是我的一个函数的例子,另一个类似,但是用 c == 'Vowel"

我的主要是这样的

ifstream file;
string word;
bool turn = true; //true for vowel, false for cons
bool done = false;

int main(int argc, char *argv[]) {
{
    file.open("phrase.txt");
    file >> word;

    if (file.eof()){
        done = true;
    }

    std::thread vowelThread(vowel); //passing vow function 
    std::thread consThread(cons); //passing cons function


    cout << file.eof() << endl; //returns true

    file.close();

    vowelThread.join();
    consThread.join();

    cout << (file.eof()) << endl; //returns true
}

为了帮助澄清问题,下面是代码应该做什么的示例。在 .txt 文件 "phrase.txt" 中,有一个简单的短语,例如 "Operating Systems Class Starts In The Evening" 输出应该是 Vowel Thread: Operating Consonant Thread: Systems Consonant Thread: Class 等等,直到文件被读完

任何帮助都将不胜感激,包括有关线程的资源或帮助我的代码的建议。提前谢谢!

【问题讨论】:

  • 文件是std::fstream ?你在哪里定义word?请提供Minimal, Complete, and Verifiable example
  • 如果不能使用同步原语,就不能使用并发。很不清楚你希望从这里使用多线程获得什么。
  • 我添加了全局变量来帮助澄清这一点。 file 是一个 ifstream 全局变量。 Word 也是一个全局变量。转身就完成了。它们是全局的,因此线程可以访问它们。
  • 为了帮助澄清问题,这里有一个代码应该做什么的例子。在 .txt 文件“phrase.txt”中,有一个简单的短语,如“Operating Systems Class Starts In The Evening” 输出应为 Vowel Thread: Operating Consonant Thread: Systems Consonant Thread: Class 等,直到文件被读取通过
  • @rhymeswithsilver 现在问题是正确的(afaik)。附带说明一下,使用跨线程的方式最好使用 std::atomic 标头完成(考虑到您不能使用互斥锁)

标签: c++ multithreading fstream


【解决方案1】:

您的代码中的主要问题是main 线程关闭了文件,而另外两个线程正在处理它,eof 位被设置也就不足为奇了(线程不能再访问关闭的@987654323 @)。 纠正这个问题的正确方法是在你的线程返回后关闭file(即在每个线程从join()返回之后)但是你的程序仍然存在一个主要缺陷,这就是你设计cons函数的方式以及您的逻辑|| 使用,出于显而易见的原因,我已将其替换为&amp;&amp;

  int main(int argc, char *argv[]) {
    {
        file.open("phrase.txt");
        file >> word;

    if (file.eof()){
        done = true;
    }

    std::thread vowelThread(vowel); //passing vow function 
    std::thread consThread(cons); //passing cons function


    cout << file.eof() << endl; //returns true

    //file.close(); <- closes file while your threads work on it, thus the eof bit is set

    vowelThread.join();
    consThread.join();
    file.close();
    cout << (file.eof()) << endl; //returns true
}

cons

void cons() {
    cout << "Turn is " << turn << endl; //outputs "Turn is 0"
    while (!file.eof()) {
        if (turn == false) {
            char c = word.at(0);
            if (c != 'A' && c != 'E' && c != 'I' && c != 'O' && c != 'U') {
                cout << "Consonant Thread: " << word << '\n';
                file >> word;
            }
            turn = true;
        }
        //this_thread::yield();
    }
}

附带说明一下,既然您已经看到 cons 中的错误,您可能会明白为什么我坚持要您提供每个功能,而不是要求我们从另一个功能中推断出一个功能。

还有最后一个问题(请注意,您的代码中有几个缺陷,为了保持话题,我没有解决):最后一个词Evening 没有输出,因为当cons 打印The 它时然后将Evening 加载到word 并设置eof 位,这意味着vowel 线程无法输入您的元音输出代码。这是一个设计流程,我相信您会知道如何解决。

如果您需要进一步的精确度,请注意不要对我的回答发表评论。

【讨论】:

  • 谢谢!这就说得通了。是的,代码肯定需要清理一下,因为我一直在研究它并试图弄清楚,而且绝对,你提到的大多数小事情都是我刚刚错过或没有的事情在我写它的时候已经考虑到了,所以它们应该很容易修复。再次感谢你:)
  • @rhymeswithsilver 太好了,不客气。既然您的问题符合所有要求的标准,我也赞成它。
猜你喜欢
  • 2014-02-09
  • 1970-01-01
  • 2019-06-02
  • 1970-01-01
  • 1970-01-01
  • 2018-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多