Linux的进程状态

04-进程管理 - 图1

ps

Process Status。查看进程状态的最常用的命令,它可以提供关于进程的许多信息。

  • 直接用ps命令可以列出每个与你的当前Shell有关的进程的基本信息。 04-进程管理 - 图2
  • ps -ef:显示系统中所有进程的全面信息。
    • -e:显示所有进程
    • -f:全格式
    • 用户ID、进程ID、父进程ID、CPU占用率、开始时间、开始此进程的终端设备、此进程运行的总时间、命令名。 04-进程管理 - 图3
  • ps aux显示所有终端上所有用户的有关进程的所有信息。

    终结进程

  • 通常来说,终结一个前台进程可以使用Ctrl+C

  • 终结一个后台进程得使用kill命令。kill <进程号>。如果想强制杀掉一个进程需要使用-9:kill -9 <进程号>

    sleep

    使进程暂停由时间值所指定的秒数。此命令大多用于shell程序设计中,使两条命令执行之间停顿指定的时间。如:sleep 100; who | grep 'root'

    wait

    wait是用来阻塞当前进程的执行,直至指定的子进程执行结束后,才继续执行。

  • wait [进程号 或 作业号]:eg:wait 23 or wait %1

  • 如果wait后面不带任何的进程号或作业号,那么wait会阻塞当前进程的执行,直至当前进程的所有子进程都执行结束后,才继续执行。

    fork()

    fork()函数会创建一个和原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事。但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。fork()调用一次,分别向父子进程返回,它可能有三种不同的返回值:

  • 在父进程中,fork()返回新创建子进程的进程ID;

  • 在子进程中,fork()返回0;
  • 如果出现错误,fork()返回一个负值;

所以我们可以通过fork返回的值来判断当前进程是子进程还是父进程。同时每个进程都有一个互不相同的进程标识符(process ID),可以通过getpid()函数获得,还有一个记录父进程pid的变量,可以通过getppid()函数获得变量的值。

题1

源代码

04-进程管理 - 图4

运行结果

04-进程管理 - 图5

分析

程序运行到第7行,创建一个新的进程,克隆一份当前进程。向父进程返回子进程的pid,向子进程返回0。所以执行后父进程进入第3个分支,子进程进入第2个分支。

题2

源代码

04-进程管理 - 图6

结果

04-进程管理 - 图7

分析

04-进程管理 - 图8

题3

源代码

04-进程管理 - 图9

结果

04-进程管理 - 图10

分析

04-进程管理 - 图11

题4

题目

04-进程管理 - 图12

分析

执行第5行之后,向父进程返回真,向子进程返回假,但是没有任何影响,此时创建了一个进程,之后父子进程创建的进程个数相同,所以只分析一个再乘以2即可。第一个子进程分析结果如下图。注意,对于A && B || C

  • 表达式A为假,B不执行,C执行;
  • 表达式A为真,B执行:
    • B为真:C不执行;
    • B为假:C执行。

所以答案是1+9*2=19个。
04-进程管理 - 图13