Linux之进程管理(1)基本介绍
什么是进程:
linux系统中,进程管理相当重要。所谓进程,就是相当于触发任何一个事件时,系统都会将此事件当成一个角色定义成为一个进程,并且给予这个进程一个IP,成为PID,同时依据启发这个进程的用户与相关属性关系,给予这个PID一组有效的权限设定。然后这个PID能够在linux上面进行的各种动作,这个PID代表一个角色。
PID的产生:
在linux中执行此程序文件中,内核并不是马上进行执行,而是根据程序文件的执行者的选项和一些相应的属性等参数,然后包括其中包含的各种文件数据,最后给予一个唯一的PID,然后系统就是根据这个PID来判断进程生死否有权限在内核中执行。当然,一个数字只是一个进程的表示,一个线性内存地址的划分表示,当然不是只是PID编号来确定这么简单。
分析程序、进程特征:
program:也叫二进制(binary)文件,放置在物理存储设备中,为实体文件。
process:程序出发后,执行者的权限、属性、程序的程序代码与所需要数据等都会被加载到内存中,操作系统并给予这个内存地址(单元)一个indentity PID。进程就是被运行的程序,程序关闭,进程也就不复存在。
子进程与父进程:
程序彼此之间是相关性的,而进程之间还具有父子关系。在liunx系统启动的时候,会打开第一个进程init,PID为1,每当进行交互式登录linunx系统之后都会产生一个进程,也就是打开一个bash终端进程,那么init进程如果被终止,所进程都会被终止,因为init是所有进程的父进程。同过ssh远程连接打开一个bash,而这个bash就是此ssh进程的子进程,而ssh进程是此bash的父进程。如果我远程通过ssh协议远程连接linux打开一个伪终端并在执行pstree命令,那么进程对应关系如下:
init(1)─sshd(3407)───sshd(10545)───bash(10549)───pstree(10582)
上帝 物理终端ssh 伪终端ssh 伪终端ssh下的bash 伪终端bash下执行pstree命令
进程直接的继承:
实例说明1:
上面我们发现当前bash进程PID为10549,那么再执行一个bash呢:
[[email protected] ~]# bash [[email protected] ~]# ps -l F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 4 S 0 10549 10545 0 75 0 - 1192 wait pts/0 00:00:00 bash 0 S 0 10647 10549 0 75 0 - 1192 wait pts/0 00:00:00 bash 4 R 0 10663 10647 0 77 0 - 1077 - pts/0 00:00:00 ps
解析:这里发现两个bash,而每个进程都两个ID,其中PID为自己的进程标示,而PPID表示parent process ID ,及父ID,那么第二个bash的PPID和第一个PID相等,都是10549,说明第一个bash是第二个bash的父ID,而ps命令的PPID为第二个bash的PID,说明,ps是第二个 bash的子进程。为了验证上面杀父进程会同时杀子进程,这里我再打开第三个bash,直接杀第二个bash:
[[email protected] ~]# bash [[email protected] ~]# ps -l F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 4 S 0 10549 10545 0 75 0 - 1192 wait pts/0 00:00:00 bash 0 S 0 10647 10549 0 75 0 - 1192 wait pts/0 00:00:00 bash 0 S 0 10674 10647 0 75 0 - 1192 wait pts/0 00:00:00 bash 4 R 0 10690 10674 0 77 0 - 1077 - pts/0 00:00:00 ps [[email protected] ~]# kill -SIGKILL 10647 [[email protected] ~]# Killed [[email protected] ~]# oexit
解析:然后所有的远程bash都被杀掉了,这是因为,虽然PID不同,但是同一终端设备同一时间类只能使用一个bash,而这个打开的bash会占用划分的线性地址,而退出这个bash,会有他的上一个bash来接管,其它此终端的bash只是在排队,这样相当于清空了划分的内存空间,那么空间没了,进程自然也就没了。
实例说明2:
上面只是说明同个地址下占用情况,但是并没有谈到继承,下面用bash里面的基础知识来做一个简单的属性继承说明:
当前只打开一个bash
[[email protected] ~]# ps -l F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 4 S 0 10803 10799 0 75 0 - 1192 wait pts/0 00:00:00 bash 4 R 0 10832 10803 0 77 0 - 1077 - pts/0 00:00:00 ps
创建一个环境变量
[[email protected] ~]# export var=extends [[email protected] ~]# echo $var extends
再此bash上再次打开一个bash
[[email protected] ~]# bash
再次输入上个bash设置的环境变量,发现已经继承了
[[email protected] ~]# echo $var extends
解析:其实这些都是linux内核模块中对应进程管理模块中规定好的,在linux中一切皆文件,那么进程就算是临时驻扎在内存中,那么linux系统上也该有文件来表示给进程们安的一个家。当然这些都在/proc目录下可以看到。
先查看我们现在所在的bash列表,那么PID为10845
[[email protected] ~]# ps -l F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 4 S 0 10803 10799 0 75 0 - 1193 wait pts/0 00:00:00 bash 0 S 0 10845 10803 0 75 0 - 1193 wait pts/0 00:00:00 bash 4 R 0 10894 10845 0 77 0 - 1077 - pts/0 00:00:00 ps
查看/proc内核系统进程相关映射文件
[[email protected] ~]# ls /proc/
说明:这里每个以数字命名的都是一个进程,其目录里存放了该进程的所有信息。
通过映射文件查看进程的名称,查看PID为1
[[email protected] ~]# cat /proc/1/cmdline | xargs -I {} echo {} init [3]
解析:这里显示为init 3。表示为运行级别为3的init进程,而cmline文件存放了就是进程的具体名称。
查看当前的bash,没记错PID应该是10845
[[email protected] ~]# cat /proc/10845/cmdline | tr ‘\0‘ ‘\n‘ bash
解析:刚才提到子bash为什么会继承父bash进程的环境变量,这里是读取了里面的文件数据,下面再次查看/proc中的临时映射数据来证明。
查看子bash的环境变量,发现真的有var变量
[[email protected] ~]# cat /proc/10845/environ | tr ‘\0‘ ‘\n‘ | grep ‘^var.*$‘ var=extends
查看父bash,却没有此变量
[[email protected] ~]# cat /proc/10803/environ | tr ‘\0‘ ‘\n‘ | grep ‘^var.*$‘
退出当前bash(子bash)
[[email protected] ~]# exit exit
再次查看还是没有
[[email protected] ~]# cat /proc/10803/environ | tr ‘\0‘ ‘\n‘ | grep ‘^var.*$‘
但是查看当前内存中环境变量却能查看到
[[email protected] ~]# env | grep ‘^var‘ var=extends
解析:这里第一个bash设置的var环境变量是保存在内存中的,而再次打开的bash继承的这个变量实际上是对这个内存地址做一个指针指向,实际上还是从该内存地址中读取此环境变量,这样说来,内存地址也就可以共享的,那么是不是有共享内存呢。
进程的优先级:
如果是单核单线程的处理器,那么一次就只能运行一个进程,cpu运行进程时,就像一个不停摇摆的指针一样,指针指向哪个内存地址,那么此内存地址就会被在此时运行,而其它的进程就会存与等待状态,等待下一次被cpu指针指向给予执行的机会。
在linux中系统内核会根据当前系统状态来给某个进程设置一个表示优先级的数值:
优先级数值:
Centos5
0-139:总有140中变化,数值越小,表示此进程优先级越高
100-139:用户可控制
0-99: 内核调整的
Centos6
0-98
实时优先级:99-0,反而值越大越高
注:使用ps命令查看的pri值并不是nice值对应的40种优先级,而是linux内核通过内存调度计算得来的一种值。
优先级高的好处:
1、获得更多的CPU运行时间;
2、更优先获得运行的机会;
进程之间的优先级让位(Nice值):
nice值:每个进程运行都会分配一个nice值,-20~19。
默认nice值为0,nice值越小优先级越高
普通用户仅能够调大自己的进程的Nice值。
解析:从nice单词词义来看,为友好的,可以理解为友好值,而调低自己的nice值,也就是提示自己的优先级,那么其他用户的进程就会排在该用户进程的后面。像是抢占了 cpu资源,这样就会间接降低其它用户进程优先级。所以,只能普通用户自己降低自己的优先级,来让其它用户进程来优先运行,才符合nice标准,也就是牺牲自己的优先级来间接提升他人进程优先级。
就上述来总结进程的相关信息:
1、进程的属性信息:
进程号、内存空间、执行用户、父进程、RuntTime(运行时长)
2、进程空间划分分类:
用户空间:用户执行的进程
内核空间:系统启动的进程
3、进程的类型:
按系统运作划分:
守护进程:deamon,在系统引导过程中启动的进程,和终端无关的进程
前台进程:跟终端相关,通过终端启动的进程
注意:两种可相互转化
按运算划分:
CPU-Bound:CPU密集信息,非交互
IO-Bound:IO密集性型,交互
4、进程空间表:
堆:存放全局变量,不断增长
堆:本地变量
5、为了防止进程之间互相覆盖:
线性内存:使用Page Frame叶框,用存页面数据,存储Page 4K
物理内存:LRU;近期最少使用算法,释放内存
MMU:Memory Managerment Unit ,linux内核中对于线性地址和物理地址的转发单元
6、内存数据:
VSZ :虚拟内存大小
RSS :常驻内存集,不会被交换出去
7、进程间通信IPC(Inter Process Communication):
同一主机上:
signal:单进程通信
shm:shared memory 共享内存地址
semophore:才用一种计数器来计算信号量
不同主机上:
rpc:remote procedure call 远程进程通信调用
使用sokect(套接字):与双方IP和端口号对接
8、PID:Process ID说明:
除了PDI为1的进程,每个进程都有自己的父进程。
/proc 进程文件路径
在此路径上每个进程会产生一个以其进程PID命名的目录,每个进程号是唯一的,即使进程退出,用过的进程也不会被禁用。
9、上帝进程PID(0):
在CentOS5、6中使用init进程
[[email protected] testdir]# ps axo pid,comm | grep --color ‘[[:space:]]1\>‘ 1 init [[email protected] testdir]# pstree -l -p | head -n 1 | tr -s ‘+-‘ ‘ ‘ | cut -d ‘ ‘ -f 1 init(1)
在CentOS7中使用systemd进程
[[email protected] ~]# pstree -p -l -n | head -n 1 | grep -o --color ‘^[a-z]\+\>(1)‘ systemd(1) [[email protected] ~]# ps xo pid,comm | grep ‘[[:space:]]1\>‘ 1 systemd
10、进程的状态:
运行态:runing
就绪态:ready
睡眠态:
可中断:interruptable
不可中断:uninteruptable
停止态:stoped,暂停内存中,但不会被调度,触发手动启动
僵死态:zombie,结束进程,父进程结束前,子进程不关闭
睡眠状态解析:
Uninteruptable sleep:不可中断的睡眠
需要某些I/O资源来开启进程
Interruptable sleep:可中断睡眠
不需要某些外部I/O资源调用,随时和唤醒
(thread)单进程多线程模型优点:
让进程在多个cpu创建多个执行流,并行执行流,并共享打开的文件,来节省空间。
线程中队列通过加锁和解锁的模式来指定每个进程的运行机会。