使用向量和 pthreads 的不一致计数

Inconsistent Tally Using vectors and pthreads

所以我正在开发一个简单的程序来计算来自多个文本文件的选票(每个文件的每一行包含其中一位候选人的姓名,代表一票)。

我大部分时间都在工作,还有一个问题:每位候选人的总票数对于给定的候选人来说是不准确的,除非该候选人在每个[=41]中的票数完全相同=] votes.txt 文件。顺序没有区别。

例如:如果votes1.txt是目标目录中的唯一文件,并且每个候选人都有1票:

votes1.txt:

Clinton
Cruz
Kasich
Sanders
Trump

每次我 运行 程序产生的最终计数将正确地有 1 票。

类似地,如果目标目录有 votes1.txtvotes2.txt 并且每个候选人都有 1 票(以任何顺序),最终计票将正确地为每个候选人 2 票。

然而,一旦文本文件开始对候选人获得不同数量的选票,我就会在最终计票中得到不正确和不一致的总数。

EG:如果votes1.txtvotes2.txt的内容如下:

votes1.txt:

Clinton
Cruz
Kasich
Sanders
Trump

votes2.txt:

Clinton
Cruz
Kasich
Clinton
Sanders
Trump

克林顿的最终统计结果将不正确(在这种情况下,它仍然是 2 个而不是 3 个)。但是,如果这些文件都为克林顿投了 2 票,那么最终的统计结果将再次正确,克林顿总共有 4 票,其余各有 2 票。 votes.txt 文件越大,越不一致,最终总数只会越来越离谱。

这是一个非常奇怪且具体的错误,但通过我的代码梳理我无法查明是什么导致了它。

相关代码如下:

int main(int argc, char *argv[])
{
    vector<string> voteTallyFiles;
    vector<voteTally> intermVoteTallies;
    voteTally finalVoteTally;
    string args;
    voteTally returnValue;
    void *returnValueP;
    void *argp;
    int index = 0;

    //Grab vote tally files from Target Directory
    getFileNames(voteTallyFiles);

    vector<pthread_t> threads(voteTallyFiles.size());

    //Count the votes using pthreads and a thread function
    for (vector<pthread_t>::iterator iter = threads.begin(); iter != threads.end(); ++iter, index++)
    {
        args = voteTallyFiles[index];
        argp = &args;
        pthread_create(&*iter, NULL, &countVotes, argp);
    }

    // Wait for the threads
    for (vector<pthread_t>::iterator iter = threads.begin(); iter != threads.end(); ++iter)
    {
        pthread_join(*iter, &returnValueP);
        returnValue = *((voteTally*)returnValueP);
        intermVoteTallies.push_back(returnValue);
    }   

    // Aggregate sub-tallies
    for (unsigned int i = 0; i < intermVoteTallies.size(); i++)
    {
        finalVoteTally.pres1 += intermVoteTallies[i].pres1;
        finalVoteTally.pres2 += intermVoteTallies[i].pres2;
        finalVoteTally.pres3 += intermVoteTallies[i].pres3;
        finalVoteTally.pres4 += intermVoteTallies[i].pres4;
        finalVoteTally.pres5 += intermVoteTallies[i].pres5;
    }

    return 0;
}

void* countVotes(void *argp)
{
    string* actualArgs = (string*)argp;
    string fileName = *actualArgs;

    string line;
    ifstream inFile;
    voteTally *subTally = new voteTally;

    inFile.open(fileName.c_str());

    while (getline(inFile, line))
    {
        if (line == PRES1)
        {
            subTally->pres1++;
        }
        else if (line == PRES2)
        {
            subTally->pres2++;
        }
        else if (line == PRES3)
        {
            subTally->pres3++;
        }
        else if (line == PRES4)
        {
            subTally->pres4++;
        }
        else if (line == PRES5)
        {
            subTally->pres5++;
        }
    }
    return subTally;
}

这是一个问题:

args = voteTallyFiles[index];
argp = &args;
pthread_create(&*iter, NULL, &countVotes, argp);

在上面的行中,您将 argp 传递给线程,但它们都指向完全相同的局部变量 args,这意味着所有线程可能使用相同的数据。

而是使用寻址运算符将指针传递给 voteTallyFiles[index]

pthread_create(&*iter, NULL, &countVotes, &voteTallyFiles[index]);