【问题标题】:How to trigger a race condition?如何触发竞态条件?
【发布时间】:2019-05-12 07:54:09
【问题描述】:

我正在研究 fuzzing 方法,我想确定哪种方法适合 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;
}

感谢您的帮助

【问题讨论】:

标签: multithreading race-condition


【解决方案1】:

可能存在许多竞争条件。您的案例之一:

一个线程:

  • 读取常用变量 (1)
  • 递增 (2)
  • 将公共成员变量设置为结果值(为 2)

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

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

结果

  • 成员值只增加了 1(到值 2),但它应该增加 2(到值 3),因为有两个线程在作用于它。

测试竞争条件:

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

触发

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

希望这会有所帮助, 维托德

【讨论】:

  • @Shalaleh - 添加了更多详细信息。
  • 感谢您的解释,我已经编辑了我的帖子。如果您再看看我的问题,我将不胜感激。
猜你喜欢
  • 2010-12-22
  • 2021-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-14
  • 1970-01-01
  • 2018-10-16
相关资源
最近更新 更多