进程:一个程序被加载到内存当中运作,那么在内存中的那个数据就被称为进程(process)
进程如何产生呢?
很简单,执行一个程序或指令就可以触发一个事件而取得一个PID。
在 Linux 系统当中:
触发任何一个事件时,系统都会将他定义成为一个进程,并且给予这个进程一个 ID ,称为 PID,同时依据启发这个进程的用户与相关属性关系,给予这个 PID 一组有效的权限设定。
关于程序和进程的区别:
-
程序 (program): 通常为 binary program ,放置在储存媒体中 (如硬盘、光盘、软盘、磁带等), 为实体文件的型态存在;
-
进程 (process): 程序被触发后,执行者的权限与属性、程序的程序代码与所需数据等都会被加载内存中, 操作系统并给予这个内存内的单元一个标识符 (PID),可以说,进程就是一个正在运作中的程序。
有一个很好的例子:
当我们要操作系统的时候,无论是远程联机还是直接在主机上登入,都需要先取得一个shell
我们的shell一般是在/bin/bash, 也就是说每个人登入的时候都是执行/bin/bash
这时,系统已经给了我们一个PID,这个PID依据的是登入者的UID/GID来的
当用户在shell里进行其他作业时,就会沿用这一进程的权限
这里执行的/bin/bash就是程序,执行后拿到的shell就是进程
然后来说说子进程和父进程:
上面提到在shell里进行其他作业,这里会产生所谓的“衍生出来的进程”
比如,我们在shell里用touch新建一个文件
这里的touch指令就会被触发成一个PID,那么这个后来执行的指令就是“子进程”,原本的bash环境就是“父进程”了
再比如:
Linux-3-1.png
ps:我的bash配置文件中加了一行“cd 桌面”,所以每次衍生bash都会有一句“没有那个文件或目录”的报错
这里就是在bash环境里生了一堆小bash
可以看到后一个bash的PPID和前一个的PID是相同的,表明了他们的父子关系
另外,父子间不仅权限相同,环境变量也会继承下去的
在Linux的日常使用过程中,如果你发现某个进程被杀死后,过一阵子又自动产生了,而且PID也改变了,不要怀疑,如果不是crontab计划任务的影响,那么一定是有个父进程在偷偷地不断生娃!
还有一点要提一下就是进程间的呼叫:
在 Linux 下的进程呼叫通常称为 fork-and-exec的流程
进程都会借由父进程以复制 (fork) 的方式产生一个一模一样的子进程
然后被复制出来的子进程再以 exec 的方式来执行实际要进行的程序
最终就成为一个子进程的存在
流程如图:
Linux-3-2.png这里有解释一下fork和exec两种方式:
fork启动一个新进程时,几乎是原进程的一个拷贝,子进程和父进程使用相同的代码段, 父进程的所有数据都会留给子进程,但是子进程一旦开始运行,它们之间不再共享数据
关于exec呢,则可以理解为进程替换,一个进程一旦调用了exec类函数,本身就“死亡”了 系统把代码替换成新程序的代码,废弃原有的数据段和堆栈段并重新分配,只留下了进程号
比如:
如果在bash环境下直接输入exec ps,终端会直接退出
但是如果先输入bash,再exec ps则不会
所以如果一个进程想启动另一个程序的执行,一般需要fork和exec结合使用
书中还提到了一个概念——工作管理(job control)
其实无非就是学会怎么灵活使用 & , jobs, fg, bg, ctrl-z等指令
这些都比较容易掌握,而且自从学会了tmux这一终端复用神器的使用后更是轻松加愉快!
接下来是重头戏——进程观察与管理
首先学学怎么观察进程
在windows下,我经常使用任务管理器来观察进程和服务的运作情况
那么在Linux下呢?主要靠这两条命令——“ps -l”和“ps aux”
前者仅观察自己的bash相关进程,即最上层的进程是自己的bash,而没有延伸到systemd:
Linux-3-3.png后者观察系统所有进程:
Linux-3-4.png各字段的意义这里就不解释了
一般我首先比较关心的是各进程实时消耗的系统性能的数据
top命令是个很好的实时观察进程变化的工具
但是我感觉自己在用的一款工具好像更厉害的样子: 它就是dstat——谁用谁知道:)
Linux-3-5.png
然后说说进程的管理
进程之间是可以相互控制的,关键是要给予目标进程一个讯号去告知它你想让它做什么!
每个进程都有自己的id,因此我们只需要给一个讯号给目标id就行了
主要的讯号代号与名称对应关系如下图:
Linux-3-6.png举个栗子!
如果要以 ps 找出 rsyslogd 这个进程的 PID 后,再使用 kill 传送讯息,使得 rsyslogd 可以重新读取配置文件。
可以这样做:
由于需要重新读取配置文件,因此 signal 是 1 号。
至于找出 rsyslogd 的 PID 可以这样做:
ps aux | grep 'rsyslogd' | grep -v 'grep'| awk '{print $2}'
接下来则是实际使用 kill -1 PID
因此,整串指令会是这样:
kill -SIGHUP $(ps aux | grep 'rsyslogd' | grep -v 'grep'| awk '{print $2}')
如果要确认有没有重新启动 syslog ,可以参考登录档的内容,使用如下指令查阅:
tail -5 /var/log/messages
如 果 你 有 看 到 类 似
Aug 5 01:25:02 study rsyslogd: [origin software="rsyslogd" swVersion="7.4.7" x-pid="742" x-info="http://www.rsyslog.com"] rsyslogd was HUPed
之类的字样,就是表示 rsyslogd 在 8/5 有重新启动 (restart)过了!
网友评论