它是否正确?基本上,程序只是硬盘上的代码,当它们位于 RAM 中时,它们被称为进程,对吗?
答案1
虽然这可能有点笨拙,但你可以这么说。创建流程需要两个步骤:
- 分配一个你区(基本上,有关内核可访问的进程的信息),在进程表中填充一个条目,初始化所有相关组件......基本上,只需创建另一个进程供内核管理即可。这是通过
fork
系统调用完成的。 将可执行文件加载到内存中。这是通过
exec
(现在execve
)系统调用完成的。在此调用期间,3 个主内存区域,称为地区已填充:- 这文本区域,它由您的流程要遵循的一组指令组成:基本上是您的程序。它包含在您的可执行文件中(编译器根据您的源代码编写它)。
- 这数据区域,其中包含初始化数据(带有值的变量,例如
int myvar = 1
)和足够的空间来保存未初始化的数据(称为BSS),例如数组(例如char buffer[256]
)。 - 这堆地区。这部分解释起来有点棘手,正如我在评论中所说,莫里斯·J·巴赫(Maurice J. Bach)比我做得更好(第 2 章第 2.2.2 节)。基本上,堆栈是内存中的动态区域,它随着函数的调用而增长,并随着函数的返回而缩小。当执行程序时,与
main
函数对应的帧被压入堆栈。当程序终止时,这些帧将被弹出。
现在,虽然这似乎足以运行一个程序,但事实并非如此。既然你的进程正在运行,内核仍然需要维护它。引用:
正如第 2 章所述,进程的生命周期在概念上可以分为一组描述该进程的状态。(UNIX 操作系统的设计,Maurice J. Bach,第 6 章:进程的结构)。
这意味着您的进程不会始终“运行”,也不会始终位于主存储(您称之为“RAM”)中。例如:
- 如果你的进程曾经进入睡眠状态(因为它是由它的文本,或者因为它正在等待某些东西),内核可能决定将其交换到辅助存储(通常是交换区域)。发生这种情况时,您的进程不再位于主存储中(“内存/RAM”中):内核已保存它,并且一旦将其加载回主存储中,就能够重新调度它。
- 如果您的进程运行了足够的时间,并且内核决定抢占它(并让另一个进程运行一段时间),如果它无法将其保存到内存中,它可能会再次将其交换出来。
进程的典型寿命是...
- 创建:
fork
系统调用已被使用。 - 准备运行(在内存中):指令和数据已加载。
- 运行(在用户模式和内核模式之间切换,可能会多次..)
- 睡觉,醒来,睡觉,醒来,……
- 退出(最终切换到内核模式、僵尸状态、消失)。
步骤 3 和步骤 4 实际上可能交织在一起。
注意流程是 UNIX 系统上的两个主要概念之一(以及文件)。因此,不可能以问答形式涵盖有关他们的所有内容。我在回答中不断引用的书是 UNIX 系统的绝佳参考书,虽然 *NIXes/类 UNIX 系统在某些方面可能有所不同,但它们仍然依赖于相同的概念。