跳转至

进程管理

进程的概念


点击这里,看视频讲解,学习下面内容

大家比较熟悉 Windows 下的可执行文件,就是那些扩展名为exe的文件。

大家知道,只需要鼠标双击这些程序, 就可以运行了。

程序运行起来后,我们把这个程序正在运行的 实例 称之为 进程


操作系统对每个进程都分配一个数字标记,称为 进程ID (PID)。

Windows进程的信息可以通过 任务管理器看到。如下所示

image

比如上图中,正在运行的计算器程序 Calculator.exe 的进程PID就是 3164


Linux系统中,进程也有PID。

在Linux中,你正在运行的交互式命令行程序 Shell, 它就是一个进程。

我们可以用命令 ps 查看进程信息的命令。

[byhy@localhost ~]$ ps
  PID TTY          TIME    CMD
 4786 pts/0    00:00:00   bash

如上所示,当前bash shell的 进程 PID 为 4786


进程的创建与查看


点击这里,看视频讲解,学习下面内容

Linux中,一个进程A里面可以创建出一个新的进程B,进程A就叫做进程B的 父进程 (parent process)。

进程B叫做进程A的子进程(child process)。

最典型的例子,我们在shell中运行的程序(命令),都是shell进程创建的,所以shell进程就是他们的父进程。

Linux中,主要是通过ps命令来查看进程信息的,我们运行命令ps -f ,结果如下所示

[byhy@localhost ~]$ ps -f
 UID         PID  PPID  C STIME     TTY      TIME    CMD
byhy        4786  1780  0 06:45     pts/0    00:00:00  -bash
byhy        1865  4786  0 06:55     pts/0    00:00:00   ps –f

其中 PPID这一列就是该进程的父进程的PID。

我们可以看出 ps 命令对应的进程的父进程PID为4786,正是bash进程的PID。


下面列举了常用的 ps命令 的例子:

ps 显示和当前终端有关的进程信息

ps -u byhy 显示byhy用户所创建的进程信息

ps -f 详细显示每个进程信息

ps -e 显示所有正在运行的进程信息

ps -ef 显示当前系统所有的进程

ps –ef | grep python 查找python进程


进程的前台、后台转换


点击这里,看视频讲解,学习下面内容

Linux终端通过Shell程序来接收用户输入的命令,并且执行命令。

我们在Shell里正在执行的,和用户进行人机交互的进程叫 前台进程 (foreground process)

前台进程可以接收键盘输入并将结果显示在显示器上。

用户敲入什么命令,shell就会启动对应的程序,运行在 前台

比如,大家可以用vi 编写一个 下面的Python程序到 Linux主机上,代码文件名可以为t1.py

while True:    
    info = raw_input("please input something:")
    print("you input:%s\n\n" % info)

然后使用命令 python t1.py 运行。

可以发现及时这个 python 程序变成了前台进程,接收用户的输入。


有些程序运行时,并不需要和用户进行交互,也就是说,不需要用户输入什么内容。 比如一个日志分析程序,一个定时清理磁盘文件的程序。

比如,下面这样的一个Python程序 t2.py:

import time

while True:    
    print("execute a task ...")
    time.sleep(2)
    print("done, wait for an hour to proceed...")
    time.sleep(3600)

我们可以执行命令 python t2.py 运行它

这样的程序,运行期间,如果在前台执行,我们只能等待它结束,不然我们没法执行下个程序。

但是既然不需要用户输入信息,在前台执行,没有太大意义,我们应该要让它在 后台 执行。

要让它在后台运行,启动时只需在命令行的最后加上“&”符号。

比如 python t2.py &


后台运行的进程我们叫后台进程(background process),或者后台任务 ,它不直接和用户进行交互的进程。用户一般是感觉不到后台进程程序的运行。


当在后台运行命令时,有时需要其输出重定向输出到一个文件中去,以便以后检查。

比如 在后台运行find命令,在当前目录及其子目路下查找文件名为 byhy 的文件。

$ find . -name byhy -print > log.txt &
4762

重定向的概念后面会讲。


nohup


点击这里,看视频讲解,学习下面内容

我们可以执行命令的时候,使用 & 结尾使进程在后台运行。

但是如果终端关闭,那么程序也会被关闭,因为shell会发送SIGHUP信号给这些进程。进程接收的该信号,如果没有特别的处理,缺省就会结束运行

为了避免这种情况,那么我们就可以使用 nohup 这个命令。

比如我们有个test.sh 需要在后台运行,并且希望在后台能够一直运行,即使关闭了终端,也不退出。那么就使用nohup:

nohup /root/test.sh &


进程的终止


点击这里,看视频讲解,学习下面内容

进程一般有两种终止方式。

  • 自行终止

有的进程执行完一段任务后,就自行退出了。

比如上面的ps命令,它执行完查看进程信息的任务后,就会结束。

也有的不是自动退出,而是用户操作它,让它退出。 比如 我们在Shell进程中运行exit命令后,该Shell进程就会退出。

也有的是异常退出,比如程序有个bug(比如代码里面有除以0的指令),该程序无法执行下去,也会终止。

  • 被强行杀死

有的进程一直不结束,如果用户觉得该进程应该被强行结束了,该怎么办呢?


对于一个前台进程,要结束它,我们只需要按组合键: Ctrl + C


对于一个后台运行的进程 ,如果用户觉得该进程应该被强行结束,可以使用 kill -9 命令强行杀死该进程。

比如上面的 python t2.py 命令运行的进程。 我们可以先用ps命令查出它的进程PID,

[byhy@localhost ~]$ ps -f
UID        PID  PPID  C STIME TTY       TIME     CMD
byhy       2281  1780  0 06:45 pts/0    00:00:00 -bash
byhy       1442  2281  0 07:19 pts/0    00:00:00 python pt.py
byhy       1911  2281  1 07:20 pts/0    00:00:00 ps -f

如上所示的python进程PID为 1442,我们再执行命令 kill -9 1442。 这样就强行停止了该进程。

要注意的是, 上面所示的进程启动它的用户为byhy,那么只能是用户byhy或者root用户才能杀死该进程

您需要高效学习,找工作? 点击咨询 报名实战班

点击查看学员就业情况

环境变量

Shell是个特殊的进程,因为我们通过它来执行命令,启动其他的进程的。所以它是很多进程的父进程。

Shell 这个父进程有很多特性会影响到我们执行命令,其中非常重要的一个就是 环境变量

环境变量 设置了 进程运行的环境信息。

Linux 的环境变量具有继承性,即:子进程 会继承父进程 的环境变量。

我们可以用命令printenv来查看当前shell的环境变量。

  • 环境变量PATH

我们可以看到环境变量有很多,通常我们最关注的一个就是环境变量是其中的 PATH

因为PATH 决定了当我们敲入命令的时候,到哪里去找这个命令对应的可执行程序。

用命令 echo $PATH 来查看环境变量PATH的值,比如

[byhy@localhost ~]$ echo $PATH
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/byhy/bin
当我敲入命令ps后,shell就会 依次 到下面的路径去寻找ps命令对应的可执行文件 /usr/local/bin -> /bin -> /usr/bin -> /usr/local/sbin -> /usr/sbin -> /sbin -> /home/byhy/bin


  • 在环境变量PATH里面添加一个新的路径

方法一:执行命令 export PATH

比如:

export PATH=/test:$PATH

再次查看环境变量PATH的值,结果如下

[byhy@localhost ~]$ echo $PATH
/test:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/byhy/bin

说明添加PATH成功。

但是这种方式生效时临时的。再次登录的时候,PATH里面就又没有这个环境变量了。

需要一直生效,可以使用方法二。


方式二:写入到shell启动文件中

所谓shell启动文件(Startup Files)是指Shell启动时 会 自动加载执行 的文件。

既然这些文件会自动被shell加载执行,通常我们可以在里面放入一些 例行 执行的命令,比如设置一些环境变量。

bash Shell启动文件有好几个,比如 /etc/profile (所有用户共享), ~/.bash_profile , ~/.bash_login , and ~/.profile

具体细节参考这个文档

通常建议把某个用户 独有的 设置环境变量的 命令,放到用户家目录下面的 .bash_profile 文件中。

可以在文件的结尾加入一行

export PATH=/test:$PATH

好了,下次登录的时候,PATH里面就会多出/test;

如果要对当前的shell就立即生效,可以执行命令 source .bash_profile


作业和练习

打开PuTTY终端登录Linux账号byhy,vi编辑一个Python代码文件 run.py ,拷贝下面的代码进去,并保存文件

import time,os

while True:    
    print(u"byhy env is : "+os.environ.get('byhy',''))
    print(u"wait for an hour")
    time.sleep(3600)

运行命令 python run.py 启动 该程序后, PuTTY 开另外一个终端窗口 ,使用命令查看该进程的进程号 和父进程号。

接下来:

  • 结束掉 run.py 进程

  • 执行命令,保证 这个 run.py 程序在后台运行,并且关闭掉终端窗口,该程序也不会停止

  • 在当前的byhy账号添加一个环境变量 byhy,其值为 welcome , 并且设法保证 每次登录到byhy该环境变量都生效。

可以通过运行 run.py 检查 环境变量 byhy的值

  • 在当前的byhy账号的环境变量 path 值里面 添加 一个 /home/byhy/run, 并且设法保证 每次登录到byhy该环境变量都生效