当前位置 主页 > 服务器问题 > Linux/apache问题 >

    Linux进程基础教程详解

    栏目:Linux/apache问题 时间:2019-10-07 16:15

    计算机实际上可以做的事情实质上非常简单,比如计算两个数的和,再比如在内存中寻找到某个地址等等。这些最基础的计算机动作被称为指令 (instruction)。所谓的程序(program),就是这样一系列指令的所构成的集合。通过程序,我们可以让计算机完成复杂的操作。程序大多数时候被存储为可执行的文件。这样一个可执行文件就像是一个菜谱,计算机可以按照菜谱作出可口的饭菜。

    那么,程序和进程(process)的区别又是什么呢?

    进程是程序的一个具体实现。只有食谱没什么用,我们总要按照食谱的指点真正一步步实行,才能做出菜肴。进程是执行程序的过程,类似于按照食谱,真正去做菜的过程。同一个程序可以执行多次,每次都可以在内存中开辟独立的空间来装载,从而产生多个进程。不同的进程还可以拥有各自独立的IO接口。

    操作系统的一个重要功能就是为进程提供方便,比如说为进程分配内存空间,管理进程的相关信息等等,就好像是为我们准备好了一个精美的厨房。

    看一眼进程

    首先,我们可以使用$ps命令来查询正在运行的进程,比如$ps -eo pid,comm,cmd,下图为执行结果:

    (-e表示列出全部进程,-o pid,comm,cmd表示我们需要PID,COMMAND,CMD信息)

     每一行代表了一个进程。每一行又分为三列。第一列PID(process IDentity)是一个整数,每一个进程都有一个唯一的PID来代表自己的身份,进程也可以根据PID来识别其他的进程。第二列COMMAND是这个进程的简称。第三列CMD是进程所对应的程序以及运行时所带的参数。

    (第三列有一些由中括号[]括起来的。它们是内核的一部分功能,被打扮成进程的样子以方便操作系统管理。我们不必考虑它们。)

    我们看第一行,PID为1,名字为init。这个进程是执行/bin/init这一文件(程序)生成的。当Linux启动的时候,init是系统创建的第一个进程,这一进程会一直存在,直到我们关闭计算机。这一进程有特殊的重要性,我们会不断提到它。

    如何创建一个进程

    实际上,当计算机开机的时候,内核(kernel)只建立了一个init进程。Linux内核并不提供直接建立新进程的系统调用。剩下的所有进程都是init进程通过fork机制建立的。新的进程要通过老的进程复制自身得到,这就是fork。fork是一个系统调用。进程存活于内存中。每个进程都在内存中分配有属于自己的一片空间 (address space)。当进程fork的时候,Linux在内存中开辟出一片新的内存空间给新的进程,并将老的进程空间中的内容复制到新的空间中,此后两个进程同时运行。

    老进程成为新进程的父进程(parent process),而相应的,新进程就是老的进程的子进程(child process)。一个进程除了有一个PID之外,还会有一个PPID(parent PID)来存储的父进程PID。如果我们循着PPID不断向上追溯的话,总会发现其源头是init进程。所以说,所有的进程也构成一个以init为根的树状结构。

    如下,我们查询当前shell下的进程:

    root@vamei:~# ps -o pid,ppid,cmd
     PID PPID CMD
    16935 3101 sudo -i
    16939 16935 -bash
    23774 16939 ps -o pid,ppid,cmd
    

    我们可以看到,第二个进程bash是第一个进程sudo的子进程,而第三个进程ps是第二个进程的子进程。 

    还可以用$pstree命令来显示整个进程树:

    init─┬─NetworkManager─┬─dhclient
      │    └─2*[{NetworkManager}]
      ├─accounts-daemon───{accounts-daemon}
      ├─acpid
      ├─apache2─┬─apache2
      │   └─2*[apache2───26*[{apache2}]]
      ├─at-spi-bus-laun───2*[{at-spi-bus-laun}]
      ├─atd
      ├─avahi-daemon───avahi-daemon
      ├─bluetoothd
      ├─colord───2*[{colord}]
      ├─console-kit-dae───64*[{console-kit-dae}]
      ├─cron
      ├─cupsd───2*[dbus]
      ├─2*[dbus-daemon]
      ├─dbus-launch
      ├─dconf-service───2*[{dconf-service}]
      ├─dropbox───15*[{dropbox}]
      ├─firefox───27*[{firefox}]
      ├─gconfd-2
      ├─geoclue-master
      ├─6*[getty]
      ├─gnome-keyring-d───7*[{gnome-keyring-d}]
      ├─gnome-terminal─┬─bash
      │    ├─bash───pstree
      │    ├─gnome-pty-helpe
      │    ├─sh───R───{R}
      │    └─3*[{gnome-terminal}]