当前位置: 首页 > 面试题库 >

具体来说,fork()如何处理Linux中malloc()的动态分配内存?

徐皓君
2023-03-14
问题内容

我有一个带有父进程和子进程的程序。在fork()之前,父进程称为malloc(),并在其中填充了一些数据。在fork()之后,孩子需要该数据。我知道我可以使用管道,但是以下代码似乎可以工作:

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

int main( int argc, char *argv[] ) {
    char *array;
    array = malloc( 20 );
    strcpy( array, "Hello" );
    switch( fork() ) {
    case 0:
        printf( "Child array: %s\n", array );
        strcpy( array, "Goodbye" );
        printf( "Child array: %s\n", array );
        free( array );
        break;
    case -1:
        printf( "Error with fork()\n" );
        break;
    default:
        printf( "Parent array: %s\n", array );
        sleep(1);
        printf( "Parent array: %s\n", array );
        free( array );
    }
    return 0;
}

输出为:

Parent array: Hello
Child array: Hello
Child array: Goodbye
Parent array: Hello

我知道在子级中可以使用在堆栈上分配的数据,但是似乎在子级中也可以使用在堆上分配的数据。同样,子代不能修改堆栈上父代的数据,子代不能修改堆上父代的数据。因此,我假设孩子获得了自己的堆栈和堆数据副本。

Linux总是这样吗?如果是这样,支持此操作的文档在哪里?我检查了fork()手册页,但没有特别提及堆上动态分配的内存。

谢谢


问题答案:

复制为该进程分配的每个页面(它是具有堆栈或堆的虚拟内存页面),以便派生的进程能够访问它。

实际上,它并非一开始就被复制,而是将其设置为“写时复制”,这意味着一旦其中一个进程(父级或子级)尝试修改要复制的页面,这样它们就不会对彼此造成伤害,并且仍然可以访问fork()处的所有数据。

例如,将实际可执行文件映射到内存中的代码页通常是只读的,因此会在所有分叉的进程中重用-
它们将不会再次被复制,因为没有人在此处写,只能读等等。不再需要写时复制。

可在此处和此处获得更多信息。



 类似资料:
  • 如果是,那么我需要做什么来让它们工作?

  • 动态内存分配 我们之前在 C/C++ 语言等中使用过 malloc/free 等动态内存分配方法,与在编译期就已完成的静态内存分配相比,动态内存分配可以根据程序运行时状态修改内存申请的时机及大小,显得更为灵活,但是这是需要操作系统的支持的,同时也会带来一些开销。 我们的内核中也需要动态内存分配。典型的应用场景有: Box<T> ,你可以理解为它和 malloc 有着相同的功能; 引用计数 Rc<T

  • 问题内容: 当您知道on上对象/项目的确切数量时,我非常想知道哪种内存分配方法对性能(例如,运行时间)有利,这对性能有好处。少量对象(少量内存)和大量对象(大量内存)的成本。 与 请告诉我。谢谢。 注意:我们可以对此进行基准测试,并且可能知道答案。但是我想知道解释这两种分配方法之间性能差异的概念。 问题答案: 静态分配将更快。静态分配可以在全局范围和堆栈上进行。 在全局范围内,静态分配的内存内置在

  • 问题内容: 我想在Java程序中定义一个方法拦截器,换句话说,我希望有一个在每次方法调用时执行的行为。该应用程序未在应用程序服务器中执行,因此无法在调用拦截器周围使用EJB。我在标准Java库中找到了一个不错的Proxy API,但由于它在代理创建过程中需要一个接口,因此它的功能有限: 是否有类似的API不会强制将Foo.class声明为接口? 问题答案: 为什么不使用CGLIB?有关更多信息,请

  • 本文向大家介绍请你说说C++如何处理内存泄漏?相关面试题,主要包含被问及请你说说C++如何处理内存泄漏?时的应答技巧和注意事项,需要的朋友参考一下 使用varglind,mtrace检测

  • 问题内容: 有人可以解释什么是每个请求线程和每个连接线程吗?servlet使用哪种模型?如何分配线程来处理HTTP请求?是线程/请求还是连接? 假设我要在自己的方法中异步执行耗时的任务,那么我将使用Java执行程序启动一个新线程,以便在单独的线程中进行冗长的计算并立即发送响应。 现在,这是否可以确保我释放了正在处理我的线程,或者由于子线程仍在运行而仍在使用它? 问题答案: 每个请求意味着在发出HT