内存中的静态和全局变量

时间:2010-03-10 22:48:59

标签: c++ c multithreading multiprocessing

  1. 堆栈本身存储的静态变量是否与全局变量类似?如果是这样,它们如何受到保护以仅允许本地类访问?

  2. 在多线程上下文中,担心这个内存可以被其他线程/内核直接访问吗?或者为什么我们不能在多进程/线程环境中使用static / global?

4 个答案:

答案 0 :(得分:3)

静态变量具有静态存储持续时间,因此它们通常不会放在堆栈上。对他们唯一的“保护”是他们的名字在编译时具有本地可见性。传递静态变量的地址可以访问它。

在多线程情况下使用static / globals有一个问题,即如果一个线程同时修改了一个变量,而另一个线程尝试读取它(仅举一个例子),那么读取的内容可能是坏数据。

答案 1 :(得分:3)

存储在堆栈中的变量本质上是暂时的。它们属于函数等,当函数返回并弹出相应的堆栈帧时,堆栈变量随之消失。由于全局变量被设计为可以在任何地方访问,因此它们不能脱离上下文,因此存储在堆上(或在二进制文件的特殊数据部分中)而不是堆栈上。 static变量也是如此;因为它们必须在函数的调用之间保持它们的值,所以当函数返回时它们不会消失,因此它们不能在堆栈上分配。

static变量的保护而言,IIRC主要由编译器完成。即使变量在堆上,您的编译器也知道该变量有效的有限上下文,并且从该上下文外部访问static的任何尝试都将导致“未知标识符”或类似错误。唯一不正确访问堆变量的方法是,如果您知道static的地址,并且盲目地取消引用指向它的指针。这应该导致运行时内存访问错误。

在多线程环境中,使用全局变量和静态变量仍然可以。但是,你必须要小心谨慎。您必须保证一次只能有一个线程访问该变量(通常通过某种锁定机制,如互斥锁)。对于函数内部的static局部变量,如果从多个线程顺序调用它(即从线程1调用,然后从线程2调用,然后调用线程),则必须确保函数仍能按预期运行。 1,然后是线程2等)。这通常很难做到,许多依赖static成员变量的函数都不是线程安全的(strtok是一个值得注意的例子)。

答案 2 :(得分:2)

  

堆栈本身存储的静态变量是否类似于全局变量?如果是这样,它们如何受到保护以仅允许本地类访问?

通常它们与全局变量一起存储在内存中。但是变量名称的可见性限制了访问。

  

在多线程上下文中,担心这个内存可以被其他线程/内核直接访问吗?或者为什么我们不能在多进程/线程环境中使用static / global?

问题是只有一个静态副本,所以如果多个线程正在修改变量,如果没有安全措施(关键部分)来防止这种情况,一个线程可能会导致另一个线程的更改丢失。

答案 3 :(得分:1)

  

堆栈本身存储的静态变量是否类似于全局变量?如果是这样,它们如何受到保护以仅允许本地类访问?

不,static仅指存储持续时间 - 它们可能是全局的或具有本地范围。 Globals有静态存储。

  

在多线程上下文中,担心这个内存可以被其他线程/内核直接访问吗?或者为什么我们不能在多进程/线程环境中使用static / global?

多个作家会引入歧义。您需要使用互斥锁或某种此类锁定机制来保护共享资源。

相关问题