简体   繁体   English

多线程文件读取对每个线程产生相同的结果

[英]Multi-threaded file reading produces the same result for each thread

Basically, the issue I am having is in the title, I am trying to create a multi-threaded application to read and sum up the contents of a file, this works correctly with one thread. 基本上,标题中是我遇到的问题,我试图创建一个多线程应用程序来读取和总结文件的内容,这可以在一个线程中正常工作。 However, when more are introduced they come out with the same output. 但是,当引入更多时,它们的输出相同。 How do I fix this? 我该如何解决?

The code 编码

void *sumThread(void *);
pthread_mutex_t keepOut = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t keepOutSum = PTHREAD_MUTEX_INITIALIZER;
int counter = 0, line_count = 0;
char* loc;
double total = 0;

void split(const string& s, char c, vector<string>& v)
{
    string::size_type i = 0;
    string::size_type j = s.find(c);

    while (j != string::npos)
    {
        v.push_back(s.substr(i, j - i));
        i = ++j;
        j = s.find(c, j);

        if (j == string::npos)
            v.push_back(s.substr(i, s.length()));
    }
}

int main(int argc, char* argv[])
{

    if (argc < 2)
    {

        cerr << "Usage: " << argv[0] << " filename" << endl;
        return 1;
    }

    string line;
    loc = argv[1];
    ifstream myfile(argv[1]);
    myfile.unsetf(ios_base::skipws);

    line_count = std::count(std::istream_iterator<char>(myfile),
                            std::istream_iterator<char>(),
                            '\n');

    myfile.clear();
    myfile.seekg(-1, ios::end);
    char lastChar;
    myfile.get(lastChar);
    if (lastChar != '\r' && lastChar != '\n')
        line_count++;

    myfile.setf(ios_base::skipws);
    myfile.clear();
    myfile.seekg(0, ios::beg);

    pthread_t thread_id[NTHREADS];

    for (int i = 0; i < NTHREADS; ++i)
    {
        pthread_create(&thread_id[i], NULL, sumThread, NULL);
    }

    for (int i = 0; i < NTHREADS; ++i)
    {
        pthread_join(thread_id[i], NULL);
    }

    cout << setprecision(2) << fixed << total << endl;
    return 0;
}

void *sumThread(void *)
{

    pthread_mutex_lock(&keepOut);
    int threadNo = counter;
    counter++;
    pthread_mutex_unlock(&keepOut);

    ifstream myfile(loc);
    double runningTotal = 0;
    string line;

    if (myfile.is_open())
    {
        for (int i = threadNo; i < line_count; i += NTHREADS)
        {
            vector < string > parts;

            getline(myfile, line);
            // ... and process out the 4th element in the CSV.
            split(line, ',', parts);

            if (parts.size() != 3)
            {
                cerr << "Unable to process line " << i
                        << ", line is malformed. " << parts.size()
                        << " parts found." << endl;
                continue;
            }

            // Add this value to the account running total.
            runningTotal += atof(parts[2].c_str());
        }
        myfile.close();
    }
    else
    {
        cerr << "Unable to open file";
    }

    pthread_mutex_lock(&keepOutSum);

    cout << threadNo << ":  " << runningTotal << endl;
    total += runningTotal;
    pthread_mutex_unlock(&keepOutSum);
    pthread_exit (NULL);
}

Sample output 样品输出

 2:  -46772.4
 0:  -46772.4
 1:  -46772.4
 3:  -46772.4
 -187089.72

Each thread is supposed to read and sum up the numbers in the file, then add them together when it's done. 每个线程应该读取并总结文件中的数字,然后在完成后将它们加在一起。 However, the threads all seem to return the same number even though the threadNo variable a clearly different as indicated in the output. 但是,即使threadNo变量与输出中指示的明显不同,所有线程似乎都返回相同的数字。

Your problem is here: 您的问题在这里:

for (int i = threadNo; i < line_count; i += NTHREADS) {
    vector<string> parts;

    getline(myfile, line);

getline() doesn't know the value of i , so it is still reading adjacent lines from the file, without skipping any lines. getline()不知道i的值,因此它仍从文件中读取相邻的行,而不会跳过任何行。 Hence all threads are reading the same first few lines of the file. 因此,所有线程都读取文件的相同的前几行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM