简体   繁体   English

为什么 for 循环和硬编码会产生不同的结果?

[英]Why is the for loop and the hard coded yielding different results?

I have created a program in C++ that doesn't work when the thread vectors' components are created with a for loop and does when they are created hard coded.我在 C++ 中创建了一个程序,该程序在使用 for 循环创建线程向量组件时不起作用,并且在创建硬编码时起作用。 This is the hard coded example:这是硬编码示例:

std::vector<std::thread> ThreadVector;
ThreadVector.emplace_back(std::move(std::thread([&](){cl.run(maxLast, vals[0], 0);})));
ThreadVector.emplace_back(std::move(std::thread([&](){cl.run(maxLast, vals[1],1);})));
ThreadVector.emplace_back(std::move(std::thread([&](){cl.run(maxLast, vals[2],2);})));
ThreadVector.emplace_back(std::move(std::thread([&](){cl.run(maxLast, vals[3],3);})));
ThreadVector.emplace_back(std::move(std::thread([&](){cl.run(maxLast, vals[4],4);})));

for(auto& t:ThreadVector)
        t.join();

maxLast is an integer that is the value of the double char array. maxLast是一个 integer,它是双字符数组的值。 the vals variable is a tripple char array, think a vector of strings within a vector. vals变量是一个三元字符数组,可以考虑一个向量中的字符串向量。 and the last value is a number to send through the function.最后一个值是通过 function 发送的数字。 The cl.run function basically just takes an array of char arrays, writes to a file the maxLast variable then on the next line the next string from the array. cl.run function 基本上只需要一个字符数组 arrays,将 maxLast 变量写入文件,然后在下一行写入数组中的下一个字符串。 The name of the file is called trying then the added number then .txt the function is shown below:文件名叫做trying ,然后加上数字,然后.txt function如下所示:

void dir::run(int nums, char *vals[nums], int count){
    std::cout<<"got started "<<nums<<" "<<count<<std::endl;
    std::string filestr = "trying"+std::to_string(count)+".txt";
    for(int i = 0; i < nums; i++){
        writeLine(std::to_string(nums), filestr);
        writeLine(std::string(vals[i]), filestr);
    }
}

void dir::writeLine(std::string w, std::string p){
    FILE* stream = fopen(p.c_str(), "a+");  
    fputs(w.c_str(), stream);
    fputs("\n", stream);
    fclose(stream);

}

When the hardcoded into the ThreadVector variable as shown above is run, it works perfectly.当硬编码到如上所示的ThreadVector变量中运行时,它可以完美运行。 However, if I were to run it the following way, there would be a file called trying5.txt there would also be strings I never had put into the char array printed onto the file.但是,如果我按以下方式运行它,将会有一个名为trying5.txt的文件,还会有我从未放入打印到文件上的 char 数组中的字符串。 There would also be some threads that received the same i value.也会有一些线程收到相同的i值。

int i;
int ques=5;
for(i = 0; i < ques; i++){
    printf("running %d\n", i);
    ThreadVector.emplace_back(std::move(std::thread([&](){cl.run(maxLast, vals[i],i);})));
}
for(auto& t:ThreadVector)
        t.join();

which prints on one of the runs into the terminal (cleaned up a bit):在其中一个运行中打印到终端(清理了一下):

running 0
running 1
running 2
running 3
running 4
got started 30 2
got started 30 2
got started 30 4
got started 30 3
got started 30 4

Which is obviously not what is supposed to happen, and as mentioned sometimes the terminal would print got started 30 5 and I would end up with a file named trying5.txt .这显然不是应该发生的,正如提到的,有时终端会打印got started 30 5 ,我最终会得到一个名为trying5.txt的文件。 I have also tried push_back instead of emplace_back .我也尝试过push_back而不是emplace_back

std::thread([&]

[&] means that all objects captured by the closure get captured by reference . [&]表示闭包捕获的所有对象都被引用捕获。

cl.run(maxLast, vals[i],i)

i was captured by reference. i被引用捕获了。 i was the parent execution thread's loop variable, that gets incremented on every iteration of the loop. i是父执行线程的循环变量,在循环的每次迭代中都会递增。

C++ gives you no guarantees, whatsoever, when each execution thread executes anything, in relation to anything in the parent execution thread, unless explicit synchronization takes place. C++ 不保证每个执行线程何时执行与父执行线程中的任何内容相关的任何内容,除非发生显式同步

No such synchronization occurs here.这里没有发生这样的同步。 The parent execution thread might've already incremented i by the time the new execution thread evaluates this val[i] , as well as the discrete i parameter to the function call;当新的执行线程评估这个val[i]以及 function 调用的离散i参数时,父执行线程可能已经增加了i it already ended the current iteration of the loop and moved to the next one.它已经结束了循环的当前迭代并移至下一个迭代。 Or even iterated several times.甚至多次迭代。 Or the loop may be completely over in the parent execution thread, and i is now at its final value.或者循环可能在父执行线程中完全结束,并且i现在处于其最终值。

got started 30 2
got started 30 2
got started 30 4
got started 30 3
got started 30 4

You see exactly this result, here.你在这里看到了这个结果。 Each execution thread gets around to evaluating its i after the parent execution thread iterated, and incremented i , an unpredictable number of times.在父执行线程迭代并递增i后,每个执行线程都开始评估其i ,次数不可预测。 Some of the new execution threads even managed to evaluate i at the same time, resulting in the same observed value of i .一些新的执行线程甚至设法同时评估i ,从而得到相同的i观察值。

This is what capturing objects "by reference means".这就是“通过引用方式”捕获对象的方式。 Use [=] to capture by value instead.改为使用[=]按值捕获。 This means that each execution thread sees the value of each captured object at the time the execution thread was created.这意味着每个执行线程在创建执行线程时看到每个捕获的 object 的值。

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

相关问题 带有odeint和VexCL的Lorenz示例在不同设备上产生不同的结果 - Lorenz example with odeint and VexCL yielding different results on different devices 声明二维数组时,为什么需要硬编码宽度? - Why is a hard coded width required when declaring a two dimensional array? glsl(GPU)矩阵/矢量计算产生的结果与CPU不同 - glsl (GPU) matrix/vector calculations yielding different results than CPU 硬编码的快捷方式 - hard-coded shortcuts 为什么这个例子导致“替换失败”而不是“硬错误” - Why this example results in "substitution failure" not "hard error" 将两个不同大小的硬编码数组转换为一个二维向量 - Two Hard-coded Arrays OF DIFFERENT SIZES into One 2-Dimensional Vector 将两个不同大小的硬编码数组合并为一个二维向量 - Two different sized hard-coded Arrays into One 2-Dimensional Vector 为什么在for循环中在相同条件下会得到不同的结果? - why do I get different results with the same conditions in a for loop? 为什么库需要硬编码的矢量化而不是编译器自动矢量化 - Why do libraries need hard coded vectorizion instead of compiler auto vectorization 为什么我们不能在Struct C ++中使用硬编码或初始化值? - Why can't we use hard coded or initialize a value in Struct C++?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM