我有两个 .c 文件(main.c 和 support.c)。先编译support.c,然后编译main.c并与support.o链接。我在 support.c 中有几个非静态全局变量。
这些来自 support.c 的全局变量是如何存储的?如果 main.c 是多线程的,并且有两个线程调用 support.c 中的函数,它们是共享这些全局变量,还是每个都有自己的副本?
我有两个 .c 文件(main.c 和 support.c)。先编译support.c,然后编译main.c并与support.o链接。我在 support.c 中有几个非静态全局变量。
这些来自 support.c 的全局变量是如何存储的?如果 main.c 是多线程的,并且有两个线程调用 support.c 中的函数,它们是共享这些全局变量,还是每个都有自己的副本?
全局变量是一个全局变量,而且总是只有一个,无论你编译和链接程序有多少片段。如果多个线程同时访问全局数据,您需要自己确保正确同步。
获得全局或块静态变量的单独副本的唯一方法是声明它_Thread_local
,这是在 C11 中引入的。线程局部全局变量在线程启动时初始化,并在线程加入时释放。
我认为您可能会混淆static
关键字的用法,当它应用于 C 源代码中存在的顶级变量时(即在任何函数或方法之外),而不是static
在函数或关键字内的变量上使用时。
在源代码中在任何函数之外声明的顶级变量将是全局的,除非您将其声明为static
. 如果是static
,它将仅在该文件本地。它控制变量的范围。
如果static
在函数中声明它,它会控制变量的生命周期。在这种情况下,即使在函数调用退出后,变量也会将自身保留在内存中,从而导致其值在多个函数调用中保持不变。
如果您声明一个全局变量(即它不是static
并且在源文件中处于顶层),那么在内存中将始终只有一个它的实例。在其他源文件中,您必须将其声明为,extern
以便链接器知道查找其在目标文件中为您的其他文件定义的内存位置,但内存中只有一个。
不要忘记将全局变量声明为 volatile,否则编译器可能没有意识到它们可以被另一个线程修改并进行不安全的优化。
易失性int g_example;