本地数组和与线程交互的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 ++内存模型是:所有本地非静态变量和数组都在堆栈上分配,并且每个线程都有自己的堆栈。这是真的(即,这是标准的正式部分吗?)
答案 0 :(得分:8)
这些变量在堆栈上分配,并且由于每个线程都有自己的堆栈,因此使用本地数组是完全安全的。它们与例如它们没有区别。本地int
s。
答案 1 :(得分:2)
C ++ 98对线程没有任何说明。以其他方式写入C ++ 98但使用线程的程序没有C ++ 98定义的含义。当然,线程扩展为线程提供稳定的私有局部变量是明智的,他们通常会这样做。但是可能存在线程,但事实并非如此:例如,vfork
在某些Unix系统上创建的进程,其中父和子将在同一堆栈帧中执行,因为v
在{ {1}}表示不克隆地址空间,vfork
也不会将新进程重定向到其他函数。
在C ++ 11中,有线程支持。单独的C ++ 11线程中的单独激活链中的局部变量不会产生干扰。但是如果你超出语言范围并发出vfork
或类似的东西,那么所有的赌注都会被取消,就像之前一样。
但这是件事。 C ++现在已经关闭了。如果两个线程都调用相同的闭包怎么办?然后你有两个线程共享相同的局部变量。闭包就像一个对象,它捕获的局部变量就像成员一样。如果两个或多个线程调用相同的闭包,那么你有一个事实上的多线程对象,其成员(即捕获的词法变量)是共享的。
线程也可以简单地将其局部变量的地址传递给另一个线程,从而使它们共享。