如何触发比赛条件?

时间:2019-05-12 07:54:10

标签: multithreading race-condition

我正在研究模糊方法,并且我想确定哪种方法适合种族条件问题。因此,我对种族状况本身有疑问。 假设我们有一个全局变量,并且某些线程可以不受任何限制地访问它。我们如何触发现有的比赛条件?仅使用几个线程使用全局变量的函数就足够了吗?我的意思是只运行该功能是否会触发竞争条件?

在这里,我放了一些代码,我知道它存在竞争条件问题。我想知道哪些输入应该提供触发相应竞态条件问题的功能。

#include<thread>
#include<vector>
#include<iostream>
#include<experimental/filesystem>
#include<Windows.h>
#include<atomic>

using namespace std;
namespace fs = experimental::filesystem;


volatile int totalSum;      
//atomic<int> totalSum;     
volatile int* numbersArray;

void threadProc(int startIndex, int endIndex)
{
    Sleep(300);

    for(int i = startIndex; i < endIndex; i++)
    {
        totalSum += numbersArray[i];
    }
}

void performAddition(int maxNum, int threadCount)
{
    totalSum = 0;

    numbersArray = new int[maxNum];

    for(int i = 0; i < maxNum; i++)
    {
        numbersArray[i] = i + 1;
    }

    int numbersPerThread = maxNum / threadCount;

    vector<thread> workerThreads;

    for(int i = 0; i < threadCount; i++)
    {
        int startIndex = i * numbersPerThread;
        int endIndex = startIndex + numbersPerThread;

        if (i == threadCount - 1)
            endIndex = maxNum;

        workerThreads.emplace_back(threadProc, startIndex, endIndex);
    }

    for(int i = 0; i < workerThreads.size(); i++)
    {
        workerThreads[i].join();
    }

    delete[] numbersArray;
}

void printUsage(char* progname)
{
    cout << "usage: " << fs::path(progname).filename() << " maxNum threadCount\t with 1<maxNum<=10000, 0<threadCount<=maxNum" << endl;
}

int main(int argc, char* argv[])
{
    if(argc != 3)
    {
        printUsage(argv[0]);
        return -1;
    }

    long int maxNum = strtol(argv[1], nullptr, 10);
    long int threadCount = strtol(argv[2], nullptr, 10);

    if(maxNum <= 1 || maxNum > 10000 || threadCount <= 0 || threadCount > maxNum)
    {
        printUsage(argv[0]);
        return -2;
    }

    performAddition(maxNum, threadCount);

    cout << "Result: " << totalSum << " (soll: " << (maxNum * (maxNum + 1))/2 << ")" << endl;
    return totalSum;
}

感谢您的帮助

1 个答案:

答案 0 :(得分:0)

可能有很多比赛条件的情况。您的案例之一:

一个线程:

  • 读取通常可访问的变量(1)
  • 增加它(2)
  • 将公共成员变量设置为结果值(至2)

第二个线程在第一个线程读取公共值之后开始

  • 它读取相同的值(1)
  • 增加了它读取的值。 (2)
  • 然后将计算的值与第一个变量同时写入通用成员变量。 (2)

结果

  • 成员值仅增加了一个(值2),但由于两个线程正在作用,所以它应该增加了2(值3)。

测试比赛条件:

  • 出于您的目的(在上面的示例中),当您获得与预期不同的结果时,您可以检测到竞争状况。

触发

  • 如果出于以下目的总是希望发生上述情况,则需要协调两个线程的工作。这将使您可以进行测试
  • 但是,如果将两个线程的协调定义为以下条件,则将违反定义竞争条件:“竞争条件或竞争危害是电子,软件或其他系统的行为,其中系统的实质行为取决于顺序或时序。其他无法控制的事件。”。因此,您需要知道自己想要什么,而总的来说,竞争状况是一种不受欢迎的行为,在您的情况下,您想要发生的事情对于测试目的是有意义的。
  • 如果您通常询问的是-何时可能发生竞争状况-这取决于您的软件设计(例如,您可以使用可以使用的共享原子整数),硬件设计(例如,存储在临时寄存器中的变量)和通常运气好。

希望这会有所帮助, Witold