You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AArch64架构(树莓派3B)下函数内静态变量是否多核共享?

树莓派3B多核心共享函数静态变量的原理解析

在为树莓派3B编写自定义引导加载程序时,你发现函数内的静态变量会被所有核心共享同一值,运行的代码如下:

void kernel_main(unsigned int processor_index)
{

  static unsigned int current_processor_index = 0;

  if (processor_index == 0) {
    uart_init();
  }

  while (processor_index != current_processor_index);

  uart_send_string("Hi from processor ");
  uart_send(processor_index + '0');
  uart_send_string("!\r\n");

  current_processor_index++;
  
  if (processor_index == 0) {
    // if current_processor_index == 4 then all processors send message
    while (current_processor_index != 4)
      ;
    for (;;) {
      uart_send(uart_recv());
    }
  }
}

每个核心会挂起直到静态变量current_processor_index等于自身的processor_index,最终输出为:

Hi from processor 0!
Hi from processor 1!
Hi from processor 2!
Hi from processor 3!

这种现象的原理可以从以下三方面解释:

1. C语言静态变量的存储特性

函数内的static变量属于静态存储类别:

  • 它的内存空间不是在函数调用时分配在栈上,而是在程序启动时就被分配到全局数据段(.data或.bss段),生命周期贯穿整个程序运行过程。
  • 该变量只会被初始化一次,无论函数被调用多少次(包括多核心并行调用),所有调用都会访问同一份内存地址上的变量。

你的代码中,current_processor_index作为静态变量,在全局数据段只有一份实例,4个核心操作的都是这个唯一的内存地址。

2. 树莓派3B的多核心内存架构

树莓派3B的4个ARM Cortex-A53核心共享同一物理内存空间。在自定义引导加载程序阶段,通常尚未启用内存管理单元(MMU),无法为每个核心创建独立的虚拟地址空间,因此所有核心访问的内存都是直接映射到同一物理内存的,不存在核心专属的隔离内存区域。

3. 代码的同步执行逻辑

结合上述两点,代码的执行流程为:

  • 4个核心分别带着processor_index(0-3)进入kernel_main。
  • 核心0完成UART初始化后,因current_processor_index初始值为0,匹配自身索引,跳出循环输出信息,随后将变量加1变为1。
  • 此时核心1的循环条件1 != 1不成立,跳出循环输出信息,变量加1变为2。
  • 核心2、3依次重复该过程,直到变量被加至4,核心0进入UART回环的死循环。

这种共享的静态变量充当了一个简易的同步计数器,让4个核心按顺序完成输出,因此你会看到按索引排序的输出结果。

注意:这种同步方式存在潜在竞态风险,若没有严格的同步机制,极端情况可能出现多核心同时修改变量的问题。多核心编程中,对共享变量的修改应使用原子操作(如ARM的LDREX/STREX指令)来保证操作的原子性。

内容的提问来源于stack exchange,提问作者pwasoutside

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 02:40:32