C++ 使用带有共享全局变量的线程

C++ 使用带有共享全局变量的线程,c++,multithreading,C++,Multithreading,在线程访问共享全局变量时,我很难想出一个算法来确保互斥。我正在尝试编写一个线程函数,它可以使用全局变量,而不是将其转换为局部变量 到目前为止,我有以下代码: int sumGlobal = 0; void sumArray(int** array, int size){ for (int i=0; i<size; i++){ for (int j=0; j<size; j++){ sumGlobal += array[i][j]; } } }

在线程访问共享全局变量时,我很难想出一个算法来确保互斥。我正在尝试编写一个线程函数,它可以使用全局变量,而不是将其转换为局部变量

到目前为止,我有以下代码:

int sumGlobal = 0;

void sumArray(int** array, int size){

  for (int i=0; i<size; i++){
    for (int j=0; j<size; j++){
      sumGlobal += array[i][j];
    }
  }
}

int main(){
    int size = 4000;
    int numThreads = 4;

    int** a2DArray = new int*[size];
    for (int i=0; i<size; i++){
        a2DArray[i] = new int[size];
        for (int j=0; j<dim; j++){
          a2DArray[i][j] = genRandNum(0,100);
        }    
    }


    std::vector<std::future<void>> thread_Pool;
    for (int i = 0; i < numThreads; ++i) {

        thread_Pool.push_back( std::async(launch::async,
                        sumArray, a2DArray, size));
    }
}
int-sumGlobal=0;
无效数组(整数**数组,整数大小){

对于(int i=0;i使变量

#include <atomic>
... 
std::atomic<int> sumGlobal {0};
#include更详细地解释了什么是原子,为什么需要原子,以及原子是如何工作的


您还可以保持变量的原样,并使用互斥/锁定来保护它,正如my@Miles Budnek所解释的。问题是,一次只有一个线程可以执行受互斥保护的代码。在您的示例中,这意味着不同线程中的处理不会真正同时工作。原子方法应该ld具有更高的性能:一个线程仍然可以计算索引并读取数组,而另一个线程正在更新全局变量。

如果您不想使用@Christophe建议的同步对象,如
std::atomic
,您可以使用和手动同步对sum的访问

int sumGlobal = 0;
std::mutex sumMutex;

void sumArray(...) {
    for(...) {
        for(...) {
            std::lock_guard<std::mutex> lock(sumMutex);
            sumGlobal += ...;
        }
    }
}
int-sumGlobal=0;
std::mutex sumMutex;
空数组(…){
对于(…){
对于(…){
标准:锁和防护锁(sumMutex);
sumGlobal+=。。。;
}
}
}

请记住,所有这些锁定和解锁操作都会带来相当大的开销。

谢谢,尽管这不是我想要的解决方案。您知道在保持变量不变的情况下如何实现这一点吗?尽管在旁注中,我在尝试了您的建议后出现了编译错误。不确定原因。@傻瓜戈尔德这是一个非常小的问题改变,可能是解决你问题的最佳方案。为什么它“不完全是解决方案”你在找?@wouldsgold我已经更新了初始化以消除所有编译器上的错误消息。我已经完成了互斥以允许更长时间冻结变量的值,但我不建议在你的示例中使用这种方法。感谢视频,非常有趣!你有两个选择:1)使用锁进行互斥。2)使用原子类型和操作来避免锁的需要。感谢您的响应,这些方法非常有用。正如您所知,这不会编译,
错误:在“lock”之前缺少模板参数。
我通过添加
来编译它,但结果不正确。这会生成一个inc与非线程版本相比,
sumGlobal
的值是正确的。如果需要,我可以包括非线程版本。哎呀,修复了缺少的模板参数。请注意,我刚刚复制了该函数,因为这不是您要问的,但它不会生成数组的和。
sumGlobal
最终将是 numThreads*sum(a2DArray)
使用当前代码,因为每个线程都在对整个数组求和。如果要使用线程对数组求和,则需要以某种方式分解数组,以告诉每个线程要求和的部分。