操作系统

进程是程序执行的动态过程。可以说进程是执行中的程序,一个程序可以执行两次,但是每一次都是一个新的进程。

预备知识

  1. top

    通过 top 指令,你可以看到整个操作系统的实时详细信息。

    • 第一行(top)

      当前时间,距离上次关机时长,用户数

      load average 中的后三个数分别是1/5/15 分钟的负载情况。其数据是每隔5秒钟检查一次活跃的进程数,然后按特定算法计算出的数值。如果这个数除以逻辑CPU 的数量,结果高于5的时候就表明系统在超负荷运转了。

    • 第二行(Tasks)

      代表任务(进程)。分别是总数、运行、睡眠、已停止和僵尸。

    • 第三行(%Cpu(s))

      表示 CPU 使用情况,百分比表示

      us 代表用户空间

      sy 代表内核空间

      ni 代表该表过优先级的进程

      id 空闲的 CPU

      wa IO等待

      hi 代表硬中断

      si 代表软中断

    • 第四行(KiB Mem)

      代表内存使用情况,单位是 KB,1000000 KB 约等于 1G。

      分别是总量、空闲量、使用中、缓存量。

      linux 内存管理有其特殊性。使用中的内存总量(used)指的是现在系统内核控制的内存数,空闲内存总量(free)是内核还未纳入其管控范围的数量。纳入内核管理的内存不见得都在使用中,还包括过去使用过的现在可以被重复利用的内存,内核并不把这些可被重新使用的内存交还到free中去,因此在 linux 上 free 内存会越来越少,但不用为此担心。

      如果出于习惯去计算可用内存数,这里有个近似的计算公式:第四行的free + 第四行的buffers + 第五行的cached,按这个公式此台服务器的可用内存。

    • 第五行(KiB Swap)

      分别是总量、空闲量、使用中、缓存量。

      对于内存监控,在 top 里我们要时刻监控第五行 swap 交换分区的 used,如果这个数值在不断的变化,说明内核在不断进行内存和 swap 的数据交换,这是真正的内存不够用了。

    接下来就是一个列表了。

    PID — 进程id USER — 进程所有者 PR — 进程优先级 NI — nice 值。负值表示高优先级,正值表示低优先级 VIRT — 进程使用的虚拟内存总量,单位 kb。VIRT = SWAP+RES RES — 进程使用的、未被换出的物理内存大小,单位 kb。RES=CODE+DATA SHR — 共享内存大小,单位 kb S — 进程状态。包括

    O:进程正在处理器运行,这个状态从来木见过.
    S:休眠状态(sleeping)
    R:等待运行(runable)R Running or runnable (on run queue) 进程处于运行或就绪状态
    I:空闲状态(idle)
    Z:僵尸状态(zombie)   
    T:跟踪状态(Traced)
    B:进程正在等待更多的内存页
    D:不可中断的深度睡眠,一般由IO引起,同步IO在做读或写操作时,cpu不能做其它事情,只能等待,这时进程处于这种状态,如果程序采用异步IO,这种状态应该就很少见到了
    

    %CPU — 上次更新到现在的CPU时间占用百分比 %MEM — 进程使用的物理内存百分比 TIME+ — 进程使用的CPU时间总计,单位1/100秒 COMMAND — 进程名称(命令名/命令行)

  2. ps 指令

    显示当前进程的状态。-au 显示详细情况,ps j 可查看父进程 ID,运行状态,以及进程名字等。

  3. pstree

    进程树,默认相同名字用 * 合起来,加参数 -c 显示分叉。

  4. kill

    杀死正在运行的进程,释放资源,参数 -9 强行杀死。

实践操作

hello-getchar.c

#include <stdio.h>

int main(){
	printf("Hello World!\n");
	getchar();
	return 0;
}

利用 gcc 编译执行代码,结束之前查看该进程的内存。

利用 cat /proc/PID/maps 查看。/proc 是虚拟目录,它是系统内存的映射,我们可以通过这个目录查看内存信息。

fork

linux 是通过 fork 函数产生新的进程的。点击这篇文章学习 fork 函数 。学完后,我需要你实现以下几个 fork 函数,并让其进入睡眠,然后执行 pstree 和 ps j 指令查看进程间的结构关系。通过下面指令可以查看 PCB (进程控制块)的数量变化,第一个整数就是。

cat /proc/slabinfo | grep task_struct

forkExample

孤儿进程和僵尸进程

父进程死了子进程成了孤儿进程被 init 领养

子进程死了父进程没收尸变成僵尸进程,占用 PCB (进程控制块)。

文件描述符

ls -l /pro/PID/fd

查看文件描述符,0 是读,1是写,2 是错误日志,剩下的正整数随你用。