【问题标题】:Regarding Process modifications and address spaces关于进程修改和地址空间
【发布时间】:2010-08-12 18:02:45
【问题描述】:

当我们在 Unix Shell 的提示符下键入 vi 时, 我们可以使用 Vim 编辑器。

现在 Shell fork 另一个进程。

AFAIk 我在一本书中读到,一个进程无法修改另一个进程。 那么在 Linux 中,Shell 是如何允许我们在终端中打开 Vim 的呢?

我对 shell 是否真的在访问 Vim 的地址空间这一事实感到困惑。

【问题讨论】:

    标签: unix operating-system


    【解决方案1】:

    在 Unix 中只有一种方法可以启动用户进程 - fork(2) 系统调用。它创建调用进程的精确副本,不同之处在于调用的返回值 - 父/调用者中新进程的进程 ID (pid),子进程中为零。操作系统通过 父进程 id 属性维护这种父子关系(例如,参见ps -f 的输出)。

    幕后发生的事情是操作系统内核复制调用者的整个虚拟内存空间(这里有更多详细信息,google for Copy-On-Write 页面映射和vfork) .除非通过像mmap(2) 这样的共享内存 机制专门设置,否则不能从一个地址空间直接访问另一个地址空间。父进程可以wait(2) 为其子进程终止。

    我不会进入process groupssessions 和控制终端。这需要一张好照片。请查看APUE book 以获得详细解释。

    execve(2) 系统调用用文件中的一些可执行文件之一替换当前进程映像

    现在,shell 将其 stdinstdoutstderr 连接到 terminal emulator,继承自控制台上的 login(1) 进程,或由网络守护程序(如 sshd)动态分配,或者窗口管理器 (X)。例如,当您在 shell 中键入 vi 时,它是 forks,然后是 execs /bin/vi 程序,然后是 waits。新进程继承了打开的文件描述符,并且能够通过它们通过ioctl(2) 操作终端伪设备。

    真正的乐趣从 管道 开始,当您输入类似 ps -ef|grep bash 的内容时 - 留给读者作为练习 :)

    我在这里省略了许多有趣的细节,但希望这可以作为一个简短的介绍有所帮助。

    【讨论】:

      【解决方案2】:

      shell 只是简单地将 Vim 的终端文件描述符连接到它自己的,传递数据。

      您可能听说过“标准输入”、“标准输出”等文件描述符。当使用终端仿真器(如 XTerm 或您使用的任何东西)时,它会为在其中运行的 shell 提供接收到的击键流,并解释 shell 发送到终端的数据(颜色等)并显示它们.

      当您启动 Vim 时,shell 会启动它的进程并为该进程提供自己的输入和输出流。输入流与 shell 接收的相同,即在终端上键入的所有内容都会被 shell 接收,然后将其发送到 Vim。 Vim 发送到其输出流中的所有内容都会被 shell 接收,然后发送到终端。

      基本上,数据的双向流动是这样的:

      terminal emulator <====> shell <====> vim
      

      【讨论】:

      • 请详细说明,对您有帮助!
      • 不太正确。外壳不会来回“传递”任何东西。它执行fork(2) 然后execve(2) 来启动一个进程。 fork(2) 系统调用让子进程inherit 打开文件描述符,execve(2) 让它们为新进程映像打开。
      • @Xaero,“修改流程”到底是什么意思?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-11
      相关资源
      最近更新 更多