Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何在处理器中创建进程?_Linux_Unix_Process_Linux Kernel_Kernel - Fatal编程技术网

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

Linux 如何在处理器中创建进程?,linux,unix,process,linux-kernel,kernel,Linux,Unix,Process,Linux Kernel,Kernel,当我在unix/Linux中执行一个程序时,幕后到底发生了什么 谁负责创建流程 我是否需要调用内核来启动进程(我的程序实例)?从这个意义上说,我的程序应该在处理器上运行,以便进行内核调用,对吗?那么,第一个内核调用是如何在进程开始时发生的呢。这是僵局吗?那么内核在哪里第一次出现呢 抱歉,我刚刚读了很多关于这些的文档,但仍然无法连接点或获得完整的图片。有人能简单地解释一下吗?你的程序是由其他人而不是你的程序启动的(否则这将是鸡蛋和鸡的悖论)。假设您从某个shell运行程序,shell对负责启动新进

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

谁负责创建流程

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


抱歉,我刚刚读了很多关于这些的文档,但仍然无法连接点或获得完整的图片。有人能简单地解释一下吗?

你的程序是由其他人而不是你的程序启动的(否则这将是鸡蛋和鸡的悖论)。假设您从某个shell运行程序,shell对负责启动新进程的Linux内核函数进行内核调用。它会启动程序所需的内存空间,并调用它的main。现在,每当您的程序需要需要cpl3时,它都会调用一个内核函数。

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

当您登录到系统时,通常会登录到“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中的工作方式通常如下所示:

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