如何触发竞争条件?
How to trigger a race condition?
我正在研究模糊测试方法,我想确定哪种方法适合 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)
- 增加它 (2)
- 将公共成员变量设置为结果值(为 2)
第二个线程在第一个线程读取公共值后立即启动
- 它读取相同的值 (1)
- 增加了它读取的值。 (2)
- 然后将计算出的值与第一个同时写入common成员变量。 (2)
结果
- 成员值只增加了 1(到值 2),但它应该增加 2(到值 3),因为有两个线程在作用于它。
测试竞争条件:
- 为了您的目的(在上面的示例中),当您得到与预期不同的结果时,您可以检测到竞争条件。
触发
- 如果您出于以下目的可能希望描述的情况始终发生 - 您将需要协调两个线程的工作。这将允许您进行测试
- 然而,如果定义为:"A race condition or race hazard is the behavior of an electronics, software, or other system where the system's substantive behavior is dependent on the sequence or timing of other uncontrollable events.",则两个线程的协调将违反定义竞争条件。所以你需要知道你想要什么,总之,竞争条件是一种不受欢迎的行为,在你的情况下,你想要发生对测试目的有意义的事情。
- 如果您一般询问 - 何时会出现竞争条件 - 这取决于您的软件设计(例如,您可以共享可以使用的原子整数)、硬件设计(例如,存储在临时寄存器中的变量) ) 和一般的运气。
希望这对您有所帮助,
维托尔德
我正在研究模糊测试方法,我想确定哪种方法适合 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)
- 增加它 (2)
- 将公共成员变量设置为结果值(为 2)
第二个线程在第一个线程读取公共值后立即启动
- 它读取相同的值 (1)
- 增加了它读取的值。 (2)
- 然后将计算出的值与第一个同时写入common成员变量。 (2)
结果
- 成员值只增加了 1(到值 2),但它应该增加 2(到值 3),因为有两个线程在作用于它。
测试竞争条件:
- 为了您的目的(在上面的示例中),当您得到与预期不同的结果时,您可以检测到竞争条件。
触发
- 如果您出于以下目的可能希望描述的情况始终发生 - 您将需要协调两个线程的工作。这将允许您进行测试
- 然而,如果定义为:"A race condition or race hazard is the behavior of an electronics, software, or other system where the system's substantive behavior is dependent on the sequence or timing of other uncontrollable events.",则两个线程的协调将违反定义竞争条件。所以你需要知道你想要什么,总之,竞争条件是一种不受欢迎的行为,在你的情况下,你想要发生对测试目的有意义的事情。
- 如果您一般询问 - 何时会出现竞争条件 - 这取决于您的软件设计(例如,您可以共享可以使用的原子整数)、硬件设计(例如,存储在临时寄存器中的变量) ) 和一般的运气。
希望这对您有所帮助, 维托尔德