【问题标题】:Static and global variable in memory内存中的静态和全局变量
【发布时间】:2011-01-26 03:33:23
【问题描述】:
  1. 存储在堆栈中的静态变量是否类似于全局变量?如果是这样,它们如何受到保护以仅允许本地类访问?

  2. 在多线程上下文中,是否担心此内存可以被其他线程/内核直接访问?或者为什么我们不能在多进程/线程环境中使用静态/全局?

【问题讨论】:

  • 我预测这将在接下来的 10 分钟内获得 3 个赞成票,尽管之前已被问过一千次。哦,我应该说至少 3 个回复,来自那些知道这是骗子的人。
  • 也许你没有影响它。
  • 感谢所有预测!但是,我找不到完全相同的问题,因此选择询问。
  • @Neil,如果这是一个骗子,为什么不投票关闭它呢?
  • @John Dibling “我不确定我明白为什么这是一个‘问题’”——这个问题已经在 meta 上被问过很多次了。

标签: c++ c multithreading multiprocessing


【解决方案1】:

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

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

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

【讨论】:

  • 你能引用任何链接来支持“静态变量不能在堆栈上分配并且它们存储在堆上”
【解决方案2】:

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

在多线程情况下使用静态/全局变量的问题是,如果一个线程在修改变量的同时另一个线程尝试读取它(仅举一个例子),读取的可能是错误数据。

【讨论】:

  • 那么静态变量和全局变量在堆内存中?
  • 不一定。该标准没有定义“堆栈”或“堆”,因此假设所有内存都属于其中一个是不正确的。通常,全局变量存储在与程序(和进程)关联的数据部分中。从操作系统的角度来看,这可能是在堆外分配的,但从操作系统的角度来看,堆栈很可能是在堆外分配的。
【解决方案3】:

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

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

在多线程上下文中,是否担心此内存可以被其他线程/内核直接访问?或者为什么我们不能在多进程/线程环境中使用静态/全局?

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

【讨论】:

  • 如果是线程特定的静态数据怎么办?它对其他线程不明确可见,访问它的唯一方法是通过直接内存寻址,对吗?
  • 如果您的意思是在线程本地存储中,那么没有问题(除非您将地址传递给其他东西)。如果它的范围为线程过程(例如),可能仍然存在问题 - 多个线程实例可能正在执行相同的线程过程(或从中调用的其他函数)。如果您的 threadproc 只运行一个线程,那么您不必担心保护该 threadproc 本地的静态。
【解决方案4】:

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

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

在多线程上下文中,是否担心此内存可以被其他线程/内核直接访问?或者为什么我们不能在多进程/线程环境中使用静态/全局?

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-28
    • 2016-07-26
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多