进程管理
进程的概念
大家比较熟悉 Windows 下的可执行文件,就是那些扩展名为exe的文件。
大家知道,只需要鼠标双击这些程序, 就可以运行了。
程序运行起来后,我们把这个程序正在运行的 实例
称之为 进程
。
操作系统对每个进程都分配一个数字标记,称为 进程ID (PID)。
Windows进程的信息可以通过 任务管理器看到。如下所示
比如上图中,正在运行的计算器程序 Calculator.exe 的进程PID就是 3164
Linux系统中,进程也有PID。
在Linux中,你正在运行的交互式命令行程序 Shell, 它就是一个进程。
我们可以用命令 ps 查看进程信息的命令。
如上所示,当前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
然后使用命令 python3 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)
我们可以执行命令 python3 t2.py
运行它
这样的程序,运行期间,如果在前台执行,我们只能等待它结束,不然我们没法执行下个程序。
但是既然不需要用户输入信息,在前台执行,没有太大意义,我们应该要让它在 后台
执行。
要让它在后台运行,启动时只需在命令行的最后加上“&”符号。
比如 python3 t2.py &
后台运行的进程我们叫后台进程(background process),或者后台任务 ,它不直接和用户进行交互的进程。用户一般是感觉不到后台进程程序的运行。
当在后台运行命令时,有时需要其输出重定向输出到一个文件中去,以便以后检查。
比如 在后台运行find命令,在当前目录及其子目路下查找文件名为 byhy 的文件。
重定向的概念后面会讲。
nohup
我们可以执行命令的时候,使用 & 结尾使进程在后台运行。
但是如果终端关闭,那么程序也会被关闭,因为shell会发送SIGHUP信号给这些进程。进程接收的该信号,如果没有特别的处理,缺省就会结束运行。
为了避免这种情况,那么我们就可以使用 nohup
这个命令。
比如我们有个test.sh 需要在后台运行,并且希望在后台能够一直运行,即使关闭了终端,也不退出。那么就使用nohup:
进程的终止
进程一般有两种终止方式。
- 自行终止
有的进程执行完一段任务后,就自行退出了。
比如上面的ps命令,它执行完查看进程信息的任务后,就会结束。
也有的不是自动退出,而是用户操作它,让它退出。 比如 我们在Shell进程中运行exit命令后,该Shell进程就会退出。
也有的是异常退出,比如程序有个bug(比如代码里面有除以0的指令),该程序无法执行下去,也会终止。
- 被强行杀死
有的进程一直不结束,如果用户觉得该进程应该被强行结束了,该怎么办呢?
对于一个前台进程,要结束它,我们只需要按组合键: Ctrl + C
。
对于一个后台运行的进程 ,如果用户觉得该进程应该被强行结束,可以使用 kill -9
命令强行杀死该进程。
比如上面的 python3 t2.py 命令运行的进程。 我们可以先用ps命令查出它的进程PID,
byhy@byhy-server:~$ ps -f
UID PID PPID C STIME TTY TIME CMD
byhy 2368 2367 0 08:38 pts/0 00:00:00 -bash
byhy 2386 2368 0 08:39 pts/0 00:00:00 python3 t1.py
byhy 2388 2368 0 08:39 pts/0 00:00:00 ps -f
如上所示的python进程PID为2386,我们再执行命令 kill -9 2386
。 这样就强行停止了该进程。
要注意的是, 上面所示的进程启动它的用户为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命令对应的可执行文件
/usr/local/bin -> /bin -> /usr/bin -> /usr/local/sbin -> /usr/sbin -> /sbin -> /home/byhy/bin
- 在环境变量PATH里面添加一个新的路径
方法一:执行命令 export 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
, ~/.bashrc
。
通常建议把某个用户 独有的 设置环境变量的 命令,放到用户家目录下面的 ~/.bashrc
文件中。
可以在文件的结尾加入一行
好了,下次登录的时候,PATH里面就会多出/test;
如果要对当前的shell就立即生效,可以执行命令 source ~/.bashrc