linux进程
进程、程序、并发
程序:编译好的二进制文件。在磁盘上,不占用系统资源(cpu、 内存、打开的文件、设备、锁…)
进程:一个抽象概念,与操作系统原理联系紧密。进程是活跃的程序,占用系统资源。在内存中执行(程序运行起来则产生一个进程)
并发:操作系统中,一个时间段中有多个进程都处于已启动到运行完毕之间的状态。但一个时刻点上仍只有一个进程在运行(分时复用)。
cpu和MMU(内存管理单元)
存储设备包括寄存器,cache,内存,硬盘,网络等。与cpu直接打交道的应该是寄存器,多级缓存
MMU(内存管理单元), 位于CPU内部
- MMU完成虚拟地址到物理地址的映射,设置修改内存访问级别(用户空间,内核空间)。一个page是内存分配的最小单位。
虚拟内存空间产生的时间:进程启动的时候,进程的所有东西都放在虚拟内存中,并不真实存在。实际的都放在内存中,虚拟空间如何描述?
虚拟地址:可用的地址空间有4G(32位操作系统)
如果一个程序跑了两个进程:两个进程开了两个虚拟空间,两个进程互相独立。两个不同的进程共用一个内存空间。
虚拟内存和物理内存映射关系:
对于一个32位的机器来说, 每个进程都能看到4GB的虚拟地址空间, 且他们的3G~4G的位置都是kernel(每个进程都有kernel区)
从虚拟内存到物理内存的映射由MMU完成, 不同进程的用户空间被映射到物理内存的不同位置, 而不同进程的kernel空间被映射到物理内存的相同位置, 对于物理内存来说,用户空间和内核空间有不同的特权级, 从用户空间到内核空间的转换实质上是特权级的切换。
PCB
每个进程在内核中都有一个PCB来维护进程相关信息, Linux内核的进程控制块是task_struct类型的结构体。
在/usr/src/linux-headers-3.16.0-30/include/linux/sched.h
文件中可以查看struct task_struct
结构体定义。其内部成员有很多,重点需要掌握部分:
- 进程id。系统中每一个进程都有唯一的id,在c语言中用
pid_t
类型表示,其实就是一个非负整数 - 进程的状态,有就绪、运行、挂起、停止等状态
- 进程切换时需要保存和恢复的一些CPU寄存器
- 描述虚拟地址空间的信息,从虚拟地址映射到物理地址。
- 描述控制终端的信息
- 当前工作目录:cd 改变当前进程的工作目录,shell也是一个进程。
- umask掩码
- 文件描述符表,包含很多指向file结构体的指针
- 和信号相关的信息
- 用户id和组id
- 会话和进程组
- 进程可以使用的资源上限:
ulimit -a
就绪状态:等待cpu分配时间片
挂起状态:等待除cpu以外的其他资源,主动放弃cpu
环境变量
操作系统中用来指定操作系统运行环境的一些参数,通常具备以下特征:
字符串(本质)
有统一的格式:名=值[:值]
值用来描述进程环境信息。
存储形式:与命令行参数类似。char* [],数组名 environ, 内部存储字符串,NULL作为哨兵结尾。
使用形式:与命令行参数类似
加载位置:与命令行参数类似,位于用户区,高于stack的起始位置
引入环境变量表:须声明环境变量。
extern char** environ; (extern 声明)
常见环境变量:
PATH
- 可执行文件的搜索路径。
ls
命令也是一个程序,执行它不需要提供完成的路径名/bin/ls
,然而通常执行当前目录下的程序a.out
却需要提供完整的路径名./a.out
,这是因为PATH
环境变量的值里面包含了ls命令所在的目录/bin,却不包含a.out所在的目录。PATH环境变量的值可以包含多个目录,用:号隔开。在shell中用echo命令可以查看这个环境变量的值。 echo $PATH
使用date 和/bin/date原理是不同的。
- shell按照PATH中的目录从前往后查找。
- 可执行文件的搜索路径。
SHELL
- 当前shell(命令解析器),值一般是/bin/shell
TERM
- 当前终端类型,在图形界面终端下它的值通常是xterm,终端类型决定了一些程序的输出方式,比如图形界面终端可以显示汉字,而字符终端一般不行。
LANG
- 语言和locale,决定了字符编码以及时间、货币等信息的显示格式
HOME
- 当前用户主目录的路径,很多程序需要在主目录下保存配置文件,使得每个用户在运行该程序时都有自己的一套配置。
- env:查看所有环境变量
getenv函数, setenv函数