Linux学习笔记之六(进程管理上)

进程管理

进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。这里首先就要区分程序和进程了。程序是一种文件,本身不占cpu,不占内存,内核也调度不了,是存在我们磁盘上的,程序运行产生进程,进程是要吃资源的,这些资源呢,包括,cpu,内存,网络带宽,硬盘的io资源等。基于前面的原因呢,程序文件又叫做进程文件。前面也说过了,进程是有一个uid的,前面也见过,谁启动的进程一般来说进程的uid应该就是谁,但是呢?文件有一种高级权限setuid是可以把有效的uid改为文件所有者的,这是一种提权手段。我们先来看一下windows下的进程管理。

我们是可以查看进程占用资源,pid(process identification),进程的用户,进程的状态啊,进程的线程数啊等等。说到线程就不得不说下面的内容了。

线程与进程的区别与联系

相信只要接触到OS的,都避不开这个问题。下面我们就来解答一下这个问题。

参考了https://www.cnblogs.com/xdp-gacl/p/3633936.html

https://blog.csdn.net/new_teacher/article/details/51469241

http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html

通常在一个进程中可以包含若干个线程,它们可以利用进程所拥有的资源,在引入线程的操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位,由于线程比进程更小,基本上不拥有系统资源,故对它的调度所付出的开销就会小得多,能更高效的提高系统内多个程序间并发执行的程度。当下推出的通用操作系统都引入了线程,以便进一步提高系统的并发性,并把它视为现代操作系统的一个重要指标。先来看一段比较接地气的解释:QQ程序如果没有执行,那它只是程序,而不是进程,一旦执行了QQ程序,那它就成了进程。QQ程序一旦执行成了进程,操作系统如windows就要分配给QQ运行的内存空间,CPU运行的时间以及其它资源,这样QQ程序就可正常运行了。如果要运行其它程序,如杀毒软件,操作系统也要做同样的事情。有了进程之后,最大的好处就在于电脑可以同时运行多个程序,每个程序就是一个进程。而如果没有进程呢,那电脑一次只能运行一个程序,你玩QQ,就不能再同时听歌、玩游戏等等;如果你想要听歌,只能关掉QQ,再打开听歌曲的软件进行听歌了。有了进程,可以让多个程序同时运行,但每一个进程在运行时,一次只能执行一个任务,要想执行第二个任务,只能等第一个任务执行完后,再执行。但在我们现实应用中,就会出现不能等的情况,而是希望一个程序(进程)的多个任务同时执行。为达到这个目的,线程就出现了。线程可以让一个程序(进程)同时运行多个任务(并发)。比如我们用word程序时(一个进程),可能会存在三个任务:a、接受键盘输入;b、将键盘输入的内容显示在显示器上;c、输入的内容保存在硬盘上。还有百度网盘支持边下边播,下载是一个线程,播放是另一个线程。如果没有线程,那只能是程序先等键盘输入内容,然后过好长时间,再把你输入的内容显示在显示器上,等内容显示出来了,再将内容保存在硬盘上。但事实上,你在用Word时,一边输入,一边就显示了,同时也自动保存在硬盘上了(程序可设定自动保存),没有等待的感觉,这就得归功于线程的作用了。有了线程之后,你就感觉输入、显示、保存好像是同时发生一样(并发,同一时间,一并发生)。还需要说明的是一般来说呢,一个核心在一个时间点只能处理一个进程,只不过进程切换的速度很快。下面来更通俗形象地了解一下进程和线程的关系。


这里的任务是进程的意思,或者说程序的意思,因为程序的执行产生进程。

上面的cpu应该改为核心数,因为我们现在一般也都会说我的cpu是八核的。








我觉得对我们理解进程和线程还是很有帮助的。一个进程的线程之间共享由进程获得的资源,但线程拥有属于自己的一小部分资源,就是栈空间,保存其运行状态和局部自动变量的。堆是堆,栈是栈。栈可以叫做:堆栈,栈,栈和堆栈指的都是stack,只是叫法不一样。而堆就只能叫做堆。在线程中new出来的空间占的是进程的资源,也就是说是占用的堆资源(heap)。还要说的一点是,如果一个线程出了问题,可能导致整个进程出问题,比如一个工人上厕所,把门反锁,然后在里面突发心脏病当场去世了,那么其它工人(线程)就没办法上这个厕所了(没办法用这个资源了)。以前我们还看到了sudo改密码是有两个进程的。


其实也不难理解,因为sudo passwd是两个程序,有两个进程也没什么奇怪的。

进程的生命周期

PPID就是parent process id。图中说所有进程都是system'的后代,那我们来看一下。怎么看呢?用pstree看,但是我试了一下,这个命令还不是最小安装自带的(如果你安装带UI的我不确定有没有),我们需要装一个psmisc。我们用一下不带-y的yum看看是什么效果。


看到如果yum没有-y参数是会有一些询问的。安好之后,就可以使用pstree了。看到最前面的就是systemd,它就相当于亚当或者说伏羲,并且呢,这是一种并行的启动方式。

父子进程之间的关系 :
关于资源:子进程得到的是除了代码段是与父进程共享的以外,其他所有的都是得到父进程的一个副本,子进程的所有资源都继承父进程,得到父进程资源的副本,既然为副本,也就是说,二者并不共享地址空间。,两个是单独的进程,继承了以后二者就没有什么关联了,子进程单独运行。(采用写时复制技术) 
关于文件描述符:继承父进程的文件描述符时,相当于调用了dup函数,父子进程共享文件表项,即共同操作同一个文件,一个进程修改了文件,另一个进程也知道此文件被修改了。文件描述符就是识别文件的。

父进程在被子进程的结束信号唤醒以后,这个子进程就真正意义上从”僵尸“火化了,结束了自己的一生。

进程状态

计算机里面进程多,资源少。资源有哪些呢?cpu,内存,网络,磁盘io等。进程是由

有很多的,但是上面也说过一个核心在一个时间点只能处理一个进程(任务),那么Linux是如何分配资源的呢?是通过内核去调度。我们先看一下虚拟机的配置。lscpu命令即可。

每一个进程的状态是在随着对资源的要求不断变化的,所以状态决定了进程需要占用什么资源,这些要求是我们提出的,比如我现在要把vim编辑的文本保存,这是一个磁盘的io操作,文件不保存的话只是在内存里面,万一断电就GG了,所以程序员会经常保存代码,只有保存了才能写进磁盘。我现在要保存文件,vim进程可能就从睡眠状态变为运行状态了,然后内核给它分配磁盘的io资源,文件才能写进磁盘。

一个进程从它父进程fork出来以后是new的一个状态,然后经过内核的调度变成一个准备运行状态(ready),当然它还可能被暂停(suspend)进入stopped状态,了解一下stopped状态就可以了,可能有很多进程都在ready这个状态,它们都在竞争,都在等内核的同意,如果内核同意了把这个时间段的cpu分给这个进程去用,这个进程就真正处于running状态了,那个user和kernel先不用去去管,都是running状态就对了。cpu虽然应答了这个进程,但是这个进程的代码不一定就执行完了,如果没有执行完的话,就再次进入ready状态,继续竞争,如果执行完了的话,可能进入sleeping模式,这时候不需要占用cpu(但是可能占用其它资源,比如内存等,这里sleeping只是不占用cpu),但是如果有事件或者信号,还能进入ready模式。执行完毕,也可能进入zombie模式,并给父进程发送信息,父进程清理完这个进程以后,这个进程就结束了。

为了理解,举几个例子。有一个老师在讲课,台下呢,可能有很多学生举着手提问(明显不是在中国),这时候学生相当于在ready状态的进程,时刻等着老师(cpu)叫自己,然后自己就占用了老师这个资源,这个老师呢,只允许每一个学生每次问1-3个问题,如果有学生问题太多,那就得问完继续举手,就是又回到ready状态。如果问完了呢,就进入sleeping状态,不需要占用老师,但是呢,可能这个学生只是一时想不起来那么多问题,如果他听到或者看到了相关的东西又想起来了问题,那么就可以又举起手,进入ready状态。那么如果他突然肚子疼,请假回家的话,就没办法占用老师了,可以认为是这个进程就结束了。当然上面关于进程结束的例子不是很好。再举一个例子,你正在用vim编辑文本,可能你打了几行之后要再想想内容才能继续打,当你对vim里的文本没有任何操作的时候,这个进程相当于sleeping状态,不占用cpu,如果你打完了输入:wq,这个进程就先进入zombie状态,然后彻底gg。

当然,除了linux内核意以外,我们可不可以按照自己的意思来资源配置或者限制资源呢?是可以的,有两种技术,一种叫做PAM(插入式认证模块,Pluggable Authentication Modules),还有一种是CGroup 是 Control Groups 的缩写,是 Linux 内核提供的一种可以限制、记录、隔离进程组 (process groups) 所使用的物力资源 (如 cpu memory i/o 等等) 的机制。2007 年进入 Linux 2.6.24 内核,CGroups 不是全新创造的,它将进程管理从 cpuset 中剥离出来,作者是 Google 的 Paul Menage。CGroups 也是 LXC 为实现虚拟化所使用的资源管理手段。这些我们了解就可以,想再深入了解的呢,可以看一看

https://blog.csdn.net/kwame211/article/details/78730705

https://blog.csdn.net/tianyue168/article/details/41896921。

我们如何查看进程的状态呢?还是用ps这个命令,ps就是process status,这个状态在哪里呢?在

那么这些标志代表什么意思呢?

我们来看下有更详细说明的表。

R是任务在运行的意思,进程要么在cpu上运行(running),要么在等待运行(runnable)。

S是可中断的状态,也叫做浅睡眠,进程在等待一些条件叫醒他:硬件请求,系统资源访问,或者信号。当有一些满足条件的事件发生或者信号到来时,进程又回到R状态(当然一定是先进入runnable状态)。

D是不可中断睡眠状态,又称为深度睡眠状态,通常在进行磁盘的io操作时,进程就是这种状态,因为如果有很重要的文件在写入的时候,肯定时不允许被打断的,无论你怎么叫它,都叫不醒。

K和D很像,但是修改为可以对一些信号做出响应而结束进程,也就是先变为zombie然后死掉。

T是进程被用户或者其它进程给的信号停止而进入的状态,可以被信号恢复到R。

第二个T就不看了。

Z是子进程向父进程发送退出信号,除了PID保留,其它资源都释放出来的一种状态,也就是这种状态不占用任何资源,只剩下PID一个空壳。

X是父进程清理完子进程的结构体,子进程完全结束的状态,就连PID这具空壳都没有了。这种状态永远不会出现在进程列表里面。

那些+>什么的视频里没讲,我自己去查资料也很难读懂,内容还是有点深的。

<是高优先级,N是低优先级,L大概意思应该是在做实时的IO操作,s是指session 的领导,参考了

https://segmentfault.com/a/1190000009152815

session就是一组进程的集合,session id就是这个session中leader的进程ID。

session的主要特点是当session的leader退出后,session中的所有其它进程将会收到SIGHUP信号,其默认行为是终止进程,即session的leader退出后,session中的其它进程也会退出。

如果session和tty关联的话,它们之间只能一一对应,一个tty只能属于一个session,一个session只能打开一个tty。当然session也可以不和任何tty关联。

l是在多线程运行。

+是在前台进程组里面。这些附加的符号也不必太深究了。

大概来总结一下上面的东西,程序文件是存在磁盘里的,占用磁盘空间,但是不占磁盘io,不占用内存,不占用CPU,不占用网络,但是一旦用户执行了程序,就会产生进程,进程有自己的PID,还有父进程的PPID,进程有一个状态,这个状态时用户所需资源决定的,同时也对资源分配提出了要求,就像是在买东西还是排队是顾客定的,这里的顾客就相当于用户,而如果顾客在结账或者排队结账,就对商场的收银员提出了结账需求,虽然进程的管理和收银还不一样,因为收银必须一次性把眼前购买的东西都结账,而进程不一定要把代码执行完才进入sleeping或者zombie。进程占用磁盘IO,内存,CPU,网络等资源。进程有自己的生命周期,由父进程fork而来,最后结束自己的一生,当然每个进程也都会有用户和属组,有UID和GID。

进程的运行时间有长短,ls,date,rm等程序产生的进程很快就会结束,而有些守护进程,守护进程和后台还不太一样。参考了

https://blog.csdn.net/al86866365/article/details/65935987

最大的区别有几点:

(a)守护进程已经完全脱离终端控制台了,而后台程序并未完全脱离终端(在终端未关闭前还是会往终端输出结果);

(b)守护进程在关闭终端控制台时不会受影响,而后台程序会随用户退出而停止,需要在以nohup command & 格式运行才能避免影响;

(c)守护进程的会话组和当前目录,文件描述符都是独立的。后台运行只是终端进行了一次fork,让程序在后台执行,这些都没改变;

sshd是守护进程不难理解,因为它确实可以改变会话组。以上内容来自

https://www.bilibili.com/video/av18740388/?p=17

下面就要详细讲一下ps和top两个查看进程状态的命令。

查看进程状态

上面的图不是针对centos7的,说的是centos6,因为init是centos6的第一个系统进程,而现在的7是systemd。ps aux| less其中这个|是后面要讲的进程管道的内容,不过事实上我们已经用过很多次了,就先用着,到后面再来理解。加一个less是分页显示的,可以按上下键换行。

ps

我们先来看一下ps的文档,学习一下,man一下ps。当然有中文教程http://www.cnblogs.com/peida/archive/2012/12/19/2824418.html

描述:ps显示了关于被选中的活着的(不是X)的进程的信息。如果你想更新你选择的进程和进程的信息,那么就用top吧。

ps有三种格式:

  1. UNIX格式,ps后面必须带有一个破折号,也就是-。

  2. BSD格式,ps后面必须没有破折号。

  3. GNU格式,ps后面有两个破折号。

还特别强调了ps -aux和ps aux的不同:请注意"ps -aux"不同于"ps aux"。POSIX和UNIX的标准要求"ps -aux"打印用户名为"x"的用户的所有进程,以及打印所有将由-a选项选择的过程。如果用户名为"x"不存在,ps的将会解释为"ps aux",而且会打印一个警告。这种行为是为了帮助转换旧脚本和习惯。它是脆弱的,即将更改,因此不应依赖。 我们先来看一下命令参数的意思,毕竟我们不是来学英文的,还是直接看中文吧。

现在最新版本的,已经不打印任何警告信息了。

你问我用的什么版本?我们来学会查看一下版本,下面两条都行。

看到GNU了吗,我们第一讲就提到了这个组织,Linux全名就应该叫做GNU/Linux。看到Redhat应该也没什么惊讶的,因为centos就相当于红帽的个人版。

uname是打印系统信息的。

我们来皮一下,我还就新建一个叫x的用户了,然后让它运行vim。


用另一个会话看看情况。那么果然大有不同。

因为有-a,所以会出现最后一个ps。

综上呢,还是用ps aux要好一些。如果想看某一个用户的进程,可以用进程管道,后面会讲,也可以用ps -u用户名。加一个^代表以什么什么开头的。

想看某个进程,可以用-C,不过没有进程管道的信息详细。

还有有一些例子:


的确是由结构的,不过远远没有我们上讲用到的pstree直观易看。


你们自己看看就好。ps ef和ps -ef还是大有不同啊。先来看ps -e的效果。-e就是-A,显示所有进程的意思。e是环境变量的意思。

ps -e没有STIME,C和PPID。C是cpu占用,TIME是使用掉的CPU时间,STIME是启动时间,很多都是9点44分。看第一个systemd,它是所有进程的父进程,PID是1,前面曾经说过,父进程fork子进程以后,就会进入sleeping

状态,所以CPU占用率为0很好理解。

我们来详细看一下ps aux,这种BSD格式输出的参数的含义。

参考了https://www.cnblogs.com/leijiangtao/p/4049076.html。


虚拟内存和驻留内存如何理解呢?虚拟内存可以理解为建筑面积。驻留内存理解为使用面积(也不完全是)。

虚拟内存包括物理内存,还有一些共享内存,什么是共享内存呢?程序里可能有调用一些公共的库(就像楼梯,走道的面积),就是指这一块占的内存,还包含交换分区(swap)交换的一部分内存。当然驻留内存中也会有调用公共的一些库,也就是共享内存,也不是这个进程真正独占的内存,但是RSS肯定是比较接近进程独占的内存的。

看一下ps lax。


TTY是?表示不依赖于任何一个终端。

还可以按照某一个参数排序显示。但是必须是小写的。


上面是按照cpu占用率升序排序的。下面是按照内存占用降序排序,前面加一个减号就可以。(加号是可以不加的,默认是加号,就和正数前可以不加正号一样)

less功能比cat强大得多,分页显示是一点,还有搜索功能,/字符串。

来稍微看一下ps auxf的效果。是有层级的,因为f就是显示进程间关系的意思。

当然上面的命令都没有同时显示所有的参数,ps -efPPID,却没有内存的占用信息,ps aux虽然有%MEM,VSZ,RSS,但没有PPID,如果想要全部信息,就得自定义显示字段或者说显示格式。

o是自定义显示格式的意思。注意一定是axo不是auxo,因为u和o是矛盾的。



未完待续。。。

猜你喜欢

转载自blog.csdn.net/qq_41740705/article/details/80873915
今日推荐