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

使用指针时是否会发生数据竞争?fork后指针与内存变化探究

fork与指针内存的疑问解答

先看你给出的示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int *ptr;

int main(void)
{
    ptr = malloc(sizeof(int));
    if (ptr == NULL)
        return (1);
    if (fork() == 0) {
        (*ptr)++;
        printf("in child process\n");
        printf("%d\n", *ptr);
    }
    (*ptr)++;
    printf("%d\n", *ptr);
    return (0);
}

针对你的疑问逐一解答:

1. 子进程复制内存时,是仅复制指针ptr,还是其指向的实际内存也会被复制?

子进程会复制父进程的整个虚拟地址空间——包括全局变量ptr本身,以及ptr指向的那块由malloc分配的堆内存。不过这里用了**写时复制(COW)**机制:默认情况下父子进程共享同一块物理内存页,只有当其中一方试图修改这块内存时,系统才会为子进程复制出独立的物理内存页,之后双方的修改就各自作用在自己的副本上。

2. 父子进程间是否会发生数据竞争?

不会。因为写时复制的存在,当任何一方修改*ptr时,该内存页会被复制,父子进程后续的读写操作都在各自独立的物理内存上进行,不存在同时访问同一块内存的场景,自然不会有数据竞争。

3. 二者的ptr是指向不同内存地址,还是同一地址?

虚拟地址相同,但物理地址不同。fork后子进程完全继承父进程的虚拟地址布局,所以ptr变量的值(也就是它指向的虚拟地址)和父进程一模一样。但当子进程修改*ptr触发写时复制后,子进程的该虚拟地址会映射到新的物理内存页,此时父子的ptr看似指向同一个地址,实际对应的物理内存已经是两块独立的区域了。

4. 使用指针存储变量时调用fork的行为总结

  • fork后,指针变量本身会被完整复制到子进程,其存储的虚拟地址值和父进程完全一致
  • 指针指向的内存区域默认与父进程共享,只有当修改该区域时才会触发写时复制,生成子进程独有的内存副本
  • 父子进程对指针指向内存的修改互不干扰,修改操作各自作用在自己的物理内存上
  • 不存在数据竞争风险,写时复制机制已经隔离了双方的修改操作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 02:37:17