约瑟夫,回答您的最后一个问题:
当用户创建“常规”新进程时,将由fork()完成。在这种情况下,内核根本不必担心创建新堆栈,因为新过程是旧堆栈的完全复制,一直到堆栈。
如果用户使用exec()替换当前正在运行的进程,则内核确实需要创建一个新的堆栈-
但是在这种情况下,这很容易,因为它是从空白开始的。exec()擦除进程的内存空间并重新初始化它,因此内核说“ exec()之后,堆栈始终在此处存在”。
但是,如果使用clone(),则可以说新进程将与旧进程(CLONE_VM)共享一个内存空间。在这种情况下,内核无法像在调用进程中那样离开堆栈(就像fork()一样),因为那样我们的两个进程将在彼此的堆栈上踩踏。内核也不能仅仅将其放在默认位置(就像exec()一样),因为该位置已经在此内存空间中占用了。唯一的解决方案是允许调用进程为其找到位置,这就是它的作用。



