C ++局部变量和线程(不是thread_local)

时间:2013-03-05 07:08:10

标签: c++ multithreading parallel-processing thread-safety local-variables

本地数组和与线程交互的C ++ 98和C ++ 11内存模型是什么?

指的是C ++ 11 thread_local 关键字,它与全局和静态变量有关。

相反,我想知道在编译时分配的数组的线程的保证行为是什么。编译时我的意思是“int array [100]”,这与使用 new [] 关键字的分配不同。我不是指静态变量。

例如,假设我有以下结构/类:

struct xyz { int array[100]; };

以及以下功能:

void fn(int x) {
  xyz dog;
  for(int i=0; i<100; ++i)  { dog.array[i] = x; }
  // do something else with dog.array, eg. call another function with dog as parameter
  }

从多个线程调用 fn()是否安全? 似乎C ++内存模型是:所有本地非静态变量和数组都在堆栈上分配,并且每个线程都有自己的堆栈。这是真的(即,这是标准的正式部分吗?)

2 个答案:

答案 0 :(得分:8)

这些变量在堆栈上分配,并且由于每个线程都有自己的堆栈,因此使用本地数组是完全安全的。它们与例如它们没有区别。本地int s。

答案 1 :(得分:2)

C ++ 98对线程没有任何说明。以其他方式写入C ++ 98但使用线程的程序没有C ++ 98定义的含义。当然,线程扩展为线程提供稳定的私有局部变量是明智的,他们通常会这样做。但是可能存在线程,但事实并非如此:例如,vfork在某些Unix系统上创建的进程,其中父和子将在同一堆栈帧中执行,因为v在{ {1}}表示不克隆地址空间,vfork也不会将新进程重定向到其他函数。

在C ++ 11中,有线程支持。单独的C ++ 11线程中的单独激活链中的局部变量不会产生干扰。但是如果你超出语言范围并发出vfork或类似的东西,那么所有的赌注都会被取消,就像之前一样。

但这是件事。 C ++现在已经关闭了。如果两个线程都调用相同的闭包怎么办?然后你有两个线程共享相同的局部变量。闭包就像一个对象,它捕获的局部变量就像成员一样。如果两个或多个线程调用相同的闭包,那么你有一个事实上的多线程对象,其成员(即捕获的词法变量)是共享的。

线程也可以简单地将其局部变量的地址传递给另一个线程,从而使它们共享。