1

这正确地拉入了一个文本文件,但它没有以正确的顺序输出它,我需要一个线程来让出,但是当我尝试实现它时,它没有工作。每次程序运行时,它都会以随机顺序显示誓言和缺点,即使使用了 yield 函数。

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <thread>
#include <vector>
using namespace std;

void cons(string c){
//Prints consanants
cout <<"CONS:   " << c << endl;
this_thread::yield();

}

void vow(string v){
//Prints vowels
// allowing other ready threads to run
    this_thread::yield(); 
   cout <<"VOW:    " << v << endl;

}

int main() {
//Creates an array of 100
string words[100];
//Creates a starting point for i
int i = 0;
//string called x
string s;
//Takes in a file
ifstream inFile;
//Creates a vector of threads to print
vector <thread> PrintingThreads;
//Opens up the text file "phrase.txt"
inFile.open("phrase.txt");
//If It is not able to open the file
if (!inFile) {
//Display error message
   cout << "Unable to open specified file";
   //Exit with an error(1)
   exit(1); 
}
while (inFile >> s) {
words[i]=s;
i++;
}
//cycle 
for (int l=0; l<i; l++)
   {
   char first (words[l][0]);

   if ((first == 'a') || (first  == 'e') || (first  == 'i') || (first  == 'o') || (first  == 'u')||(first == 'A') || (first  == 'E') || (first  == 'I') || (first  == 'O') || (first  == 'U'))
       {
        /
       PrintingThreads.push_back(thread(vow,words[l]));

       }   


       else
       {


       PrintingThreads.push_back(thread(cons,words[l]));

       }
   }// loop with a range variable
   for (thread& t: PrintingThreads) 
       t.join();

   inFile.close();
}
4

1 回答 1

2

存在三个问题:

  1. 你不能用它this_thread::yield来确定线程的执行顺序,因为在一个特定线程中调用它,虽然建议给其他线程优先级,但并不能保证直到所有其他线程都执行完才会返回当前线程完成的。根据标准(§30.3.2/2),它只是为实现提供了重新调度的机会,但在运行时由线程调度机制决定是否重新调度,以及何时重新调度返回到当前线程。

    因此,当遇到以元音开头的行时,可能会发生以下情况:a)它启动一个元音处理线程,b)执行立即切换到该线程并处理yield命令,c)实现有机会重新调度线程所以它切换回主线程,d)主线程处理另一行可能再次是元音行,e)为新行创建一个新线程,f)yield应用命令并且实现重新安排执行并切换到另一个线程, g) 实现选择第一行的尚未完成的元音线程,因此打印该元音,完成该线程, h) 然后实现切换回第二个元音线程并完成该线程(仍然在遇到任何辅音之前), 等等。

    这只是事情发生的一种可能顺序。也可能发生第二个元音在第一个元音之前完成,或者它们都等到辅音线程开始并在两个元音线程之前完成。顺序不是由 决定的yield

  2. 即使usingyield保证等到所有其他当前正在运行的线程都完成(它不是!),也会有两个问题:a)在执行元音线程时,任何未来的辅音线程都不会仍然存在,因为您一个接一个地创建线程,所以元音线程不会有任何等待,b)另一方面,当元音线程启动时,唯一保证存在的另一个线程是主线程;但是如果元音线程必须等到主线程完成,它就必须永远等待,因为主线程join最后包含一个命令,它迫使它等待元音线程。两个线程将在永恒的死锁中相互等待。

  3. 在主程序结束时,您join按照线程插入向量的顺序执行命令。因此,即使我们假设这yield会导致一个线程等待,直到另一个线程用来join等待该线程(无论如何这是完全错误的假设),它仍然无法工作,因为辅音线程yield也包含一个语句,所以任何被连接的元音线程都必须等待跟随它的辅音线程(按照字符串的原始顺序)完成,他们不会因为他们的join命令还没有被调用。

If you want to guarantee the output to alternate between vowels and consonants (or, alternatively, to print all consonant lines followed by all vowel lines), the most straight-forward way is to do away with threads and simply put the incoming lines into two arrays (or vectors), one for vowel lines and one for consonant lines. At the end you can then easily determine the printing order, and it wouldn't consume more memory than it does already (given that you store all lines in the words array).

于 2012-10-16T01:41:13.267 回答