当前位置:   article > 正文

fork exec cow

fork exec cow

当我点击一个可执行文件时,操作系统fork了一个子进程来执行这个可执行文件,对吗?
是的,当你点击一个可执行文件时,操作系统会创建一个子进程来执行这个可执行文件。具体来说,操作系统会通过以下步骤完成这个过程:

  1. 创建子进程(fork():操作系统会调用 fork() 系统调用来创建一个新的进程(子进程)。这个子进程是父进程(通常是一个 shell 或桌面环境)的一份拷贝,但不会执行父进程的代码。

  2. 执行新程序(exec():在子进程中,操作系统会调用 exec() 系统调用,将子进程的代码段替换为可执行文件的代码。此时,子进程开始执行新加载的程序。

这样,子进程执行的就是你点击的那个可执行文件,而父进程仍然保持运行状态。通过这种机制,操作系统能够并发地运行多个程序。


exec()负责将可执行文件从磁盘装载到内存中吗?

是的,exec() 系列系统调用(例如 execve())负责将可执行文件从磁盘加载到内存中,并将当前进程的内存空间替换为这个新加载的可执行文件的内容。

具体来说,exec() 会执行以下操作:

  1. 加载可执行文件exec() 将指定的可执行文件从磁盘加载到内存中。这包括加载文件的代码段、数据段以及其他必要的段(例如 BSS 段和堆栈段)。

  2. 替换进程内存exec() 替换当前进程的地址空间,使其内容变为新加载的可执行文件的内容。原有进程的代码、数据等都会被新的程序覆盖。

  3. 设置入口点exec() 设置新的程序入口点(通常是程序的 main 函数的地址),并将程序计数器(PC)设置为这个入口点,从而开始执行新程序的代码。

  4. 重新初始化堆栈exec() 重新初始化进程的堆栈,通常会传递命令行参数和环境变量给新程序。

一旦 exec() 成功调用,进程就会丢失其原来的代码和数据,完全变成了新的可执行文件的进程。然而,进程 ID (PID) 保持不变。


写时复制(cow)在这个过程中起什么作用?

写时复制(Copy-On-Write,COW)在 fork()exec() 过程中的作用主要体现在优化内存使用和提高性能。具体来说:

1. fork() 和 COW

当操作系统调用 fork() 时,会创建一个新的子进程,这个子进程最初是父进程的一个几乎完全的拷贝,包括父进程的地址空间(内存)。如果不使用 COW,操作系统将需要将整个父进程的内存空间逐字节地复制到子进程中,这会非常消耗时间和内存。

然而,大多数情况下,子进程在 fork() 后立即调用 exec() 来执行一个新的程序,这意味着子进程会放弃当前的内存空间,加载新的可执行文件。所以,在 fork() 之后,通常不会需要父进程的内存内容。

COW 优化了这个过程:

  • 共享内存:在 fork() 时,父进程和子进程不会立即复制整个内存空间,而是共享相同的物理内存页。只有在其中一个进程试图写入这些共享内存页时,才会触发真正的内存复制操作(即写时复制)。

  • 延迟复制:这样,如果子进程在 fork() 后立即执行 exec(),因为它还没有进行任何写操作,COW 机制可以避免不必要的内存复制,大大提高了性能。

2. exec() 和 COW

当子进程调用 exec() 时,整个进程的内存空间将被新的可执行文件替换,因此,COW 机制在 exec() 调用之后失去意义。在执行 exec() 时,操作系统将释放原来的共享内存页,并加载新的程序内容到内存中。

总结

  • fork():COW 允许父进程和子进程共享相同的内存页面,直到有一个进程进行写操作。这减少了不必要的内存复制,提高了性能。
  • exec():COW 提供的内存共享机制可以避免在调用 exec() 之前进行不必要的内存复制,但在 exec() 调用之后,这些共享内存将被新加载的可执行文件所取代。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/1022458
推荐阅读
相关标签
  

闽ICP备14008679号