在parallel_for中定义的变量范围

时间:2012-04-09 11:05:53

标签: c++ multithreading thread-safety parallel-for

要并行执行循环我正在使用:

int testValues[16]={5,2,2,10,4,4,2,100,5,2,4,3,29,4,1,52};
parallel_for (1, 100, 1, [&](int i){ 
    int var1;
    for (var1=1; var1<=20000; var1++) {
        int var2, var3, var4;
        double u[45],pl;
        int values[16]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
        /* ... */
        for (var4=0; var4<16; var4++) {
            if (values[var4] != testValues[var4]) break;
        }
        /* ... */
    }
}

我可以确定parallel_for块内定义的所有变量(即var1var2var3var4uplvalues)将在每个循环迭代中具有本地范围,即不会在线程或循环迭代之间共享?

此外,多个线程只要只读取(不写入)就可以安全地访问testValues吗?

3 个答案:

答案 0 :(得分:1)

lambda中的所有变量都是执行它的线程的本地变量,所以是的,它们是安全的。

从/向testValues数组读/写理论上是一种竞争条件,但是如果你确定你只是在阅读而不是同时写或只写到数组的不同部分那么它应该是安全的。

答案 1 :(得分:1)

parallel_for循环内声明的变量遵循标准的C ++范围规则,因此它们对于执行该部分代码的每个线程都是本地的。

您只需担心外部声明的变量,如果以不安全的方式访问,可能会创建数据争用。

答案 2 :(得分:1)

这只不过是一个C ++ 11 lambda表达式。使用parallel_for并不会使它变得特别。所以它遵循这样的表达式遵循的所有规则。

就个人而言,我不会使用&作为捕获表达式,因为它太松散了,特别是对于这样的事情,你需要仔细控制在lambda表达式中使用哪些变量。

但是,是的,在lambda中声明的所有变量都是线程局部的堆栈变量。这包括lambda函数的参数列表,但不包括捕获表达式,即使您使用'by value'捕获。

默认情况下,按值捕获的变量是const,因此它们应被视为只读副本,通常是安全的。如果lambda函数被声明为可变,那么我不确定规则是如何工作的。