事实证实,有了 C 或 Python 的技能,你可以在几个小时内编写一个异常简单的 shell,像 bash 一样。(至少如不亚妹旁边能有小我若干懂一点,如不雅没有的话用时会久一点。)我已经完成啦,真的很棒。
这就是 fork
和 exec
在法度榜样中的实现。我写了一段 C 的伪代码。请记住,fork 也可能会掉败哦。
int pid = fork();
// 我要分身啦
// “我”是谁呢?可能是子过程也可能是父过程
if (pid == 0) {
// 我如今是子过程
// “ls” 吃掉落了我脑筋,然后变成一个完全不一样的过程
exec(["ls"])
} else if (pid == -1) {
// 天啊,fork 掉败了,的确是灾害!
} else {
// 我是父过程耶
// 持续做一个酷酷的美须眉吧
// 须要的话,我可以等待子过程停止
}
上文提到的“脑筋被吃掉落”是什么意思呢?
然后运行 fork()
,生成一个子过程,是我(me
)本身的一份克隆:
过程有很多属性:
- 打开的文件(包含打开的收集连接)
- 情况变量
- 旌旗灯号处理法度榜样(在法度榜样上运行 Ctrl + C 时会产生什么?)
- 内存(你的“地址空间”)
- 存放器
- 可履行文件(
/proc/$pid/exe
) - cgroups 和定名空间(与 Linux 容器相干)
- 当前的工作目次
- 运行法度榜样的用户
- 其他我还没想到的
当你运行 execve
并让另一个法度榜样吃掉落你的脑筋的时刻,实际上几乎所有器械都是雷同的! 你们有雷同的情况变量、旌旗灯号处理法度榜样和打开的文件等等。
独一改变的是,内存、存放器以及正在运行的法度榜样,这可是件大年夜事。
为何 fork 并非那么消费资本(写入时复制)
你可能会问:“如不雅我有一个应用了 2GB 内存的过程,这是否意味着每次我启动一个子过程,所有 2 GB 的内存都要被复制一次?这听起来要消费很多资本!”
事实上,Linux 为 fork()
调用实现了写时复制