如何在处理器中创建进程?

How a process is created in a processor?

当我在 unix/Linux 中执行程序时,幕后到底发生了什么?

谁负责创建进程?

我是否需要调用内核来启动进程(我的程序实例)?从这个意义上说,我的程序应该 运行 在处理器上进行内核调用,对吗?那么第一个内核调用是如何发生在一个进程的启动上的呢? .这就像一个僵局吗?那么内核首先出现在哪里?

抱歉,我刚刚阅读了很多关于所有这些的文档,但仍然无法连接点或了解全貌。有人可以详细说明一下吗?

你的程序是别人启动的,不是你的程序启动的(否则就是先有鸡还是先有蛋的悖论)。假设您 运行 来自某些 shell 的程序,shell 对负责启动新进程的 Linux 内核函数进行内核调用。它启动您的程序所需的内存 space 并调用其 main.现在,每次您的程序需要需要 cpl3 的东西时,它都会调用内核函数。

在 Unix 系统(以及大多数现代非 Unix 系统)上,进程是一棵树 - 每个进程都有一个父进程(进程 ID 为 1 的进程除外,init 进程由启动时的内核)。

当您登录系统时,您通常登录到“shell”程序的一个实例(程序=可执行文件,shell=用户交互)。在Windows上,Explorer.exe是shell。在 Unix 系统上,传统上您的 shell 类似于 bash。在 Linux 桌面上,您有一个像 Gnome 这样的图形环境,它是您的 shell,您可以将它用于 运行 程序,例如 gnome-terminal 恰好 运行另一个程序恰好是基于文本的 shell,如 bash 而不是图形 shell.

无论你的 运行 你的程序来自 Gnome,来自 bash,还是来自任何其他程序 P,无论是否交互,P 是的父进程您的进程,我们称之为 C,因此 P 是启动创建 C.

的进程

它在 Unix 中的工作方式,通常是这样的:

  1. P 实际上是 运行 宁 CPU.
  2. P调用fork()系统调用,这是一个内核API.
  3. 作为响应,内核创建进程 P 的副本作为新进程,C
  • 那时,C 不在任何 CPU 上 运行。
  • 现在你有 2 个进程,PC 是同一程序的两个独立实例。
  1. 当内核的调度程序决定 运行 C 的时候,它选择一个 CPU,并设置 CPU 的堆栈指针,数据指针,代码指针和页表指向 C 内存中的适当地址。
  2. CPU 基本上是硬件,运行 是一个始终执行下一个代码指针(“指令指针”)的循环,因此一旦将代码指针设置为新代码,它将 运行 新代码。
  • 请注意,C 中的新代码仍然是 P 中旧代码的副本。
  1. 现在C是运行ning,它调用execve()系统调用,这是另一个内核API。
  • 这是启动程序的父进程逻辑的一部分 - 您调用 fork(),然后检查您是原始 P 还是克隆 C,如果你是 C,你会打电话给 execve()
  1. 作为响应,内核创建一个新内存space(“地址space”),其中将包含新程序的堆、堆栈、代码等,将可执行文件加载到该内存中,然后将这个新内存声明为“process C”。
  • 将可执行文件加载到内存中的一部分是为 CPU 最终可以指向的堆栈指针、数据指针、代码指针和页表创建新的适当地址。
  • 特别地,代码指针的地址是新程序入口点的地址。
  1. (我在这里简化)内核的调度程序然后再次将 CPU 的指针设置为那些 C - 本质上是“重新调度”它。只有现在那些指向新内存 space.
  2. 当控制权从内核返回到 C 时,它现在指向新程序的入口点,最终将调用 main()