进程
程序、进程和线程
程序(program)是指编译过的、可执行的二进制代码,保存在存储介质如磁盘上,不运行。规模很大的二进制程序集可以称为应用
进程(process)是指正在运行的程序,包括二进制镜像,加载到内存中,还涉及很多其他方面:虚拟内存实例、内核资源打开的文件、安全上下文以及一个或多个线程
线程(thread)是进程内的活动单元。每个线程包含自己的虚拟存储器,包括栈、进程状态如寄存器,以及指令指针
在单线程的进程中,进程即线程
进程ID
每个进程都由一个唯一的标识符表示,即进程ID,简称pid。系统保证在任意时刻pid都是唯一的
空闲进程(idle process)即当没有其他进程运行时,内核所运行的进程——其pid为0。再启动后,内核运行的第一个进程为init进程,其pid为1
如果用户没有显式告诉内核要运行哪个程序,内核会尝试四个可执行文件,顺序如下:
- /sbin/init
- /etc/init
- /bin/init
- /bin/sh
分配进程ID
缺省情况下,内核将进程ID最大值设置为32768,这是为了和老的UNIX系统兼容,因为这些系统使用了有符号16位数来表示进程ID。系统管理员可以通过修改/proc/sys/kernel/pid_max把这个值设置成更大的值,但是会牺牲一些兼容性
内核分配进程ID是以严格的线性方式执行的。如果当前pid的最大值是17,那么分配给新进程的pid就为18,即使当新进程开始运行时pid为17的进程已经不再运行了。内核分配的pid值到达了/proc/sys/kernel/pid_max之后,才会重用以前已经分配过的pid值
所以内核不保证长时间进程ID的唯一性,但短时间内是稳定且唯一的
进程体系
创建新进程的那个进程称为父进程,而新进程被称为子进程。每个进程都是由其他进程创建的(除了init进程),因此每个子进程都有一个父进程。这种关系保存在每个进程的父进程ID号(ppid)中
每个进程都有属于某个用户和某个组。这种从属关系可以用来实现访问控制。对于内核来书,用户和组都不过是些整数值。通过/etc/passwd和/etc/group这两个文件,这些整数被映射成人们易读的方式。每个子进程都继承了父进程的用户和组
每个进程都是某个进程组的伊普芬,进程组表示的是该进程和其他子进程之间的关系,和前面提到的用户和组的概念不同。子进程通常属于其父进程所在的那个进程组。所有和管道相关的命令都是同一个进程组,进程组这个概念使得在管道上的进程之间发送信号或者获取信息变得很容易,同样,也适用于管道中的子进程
pid_t
从编程角度看,进程ID是由数据类型pid_t来表示的,pid_t在头文件<sys/types.h>中定义。pid_t对应的具体C语言类型是与机器的体系结构相关的,并且在任何C语言标准中都没定义它。但是,在Linux中,pid_t通常定义为C语言的int类型
获取进程ID和父进程ID
系统调用getpid()会返回调用进程的进程ID:
1 |
|
系统调用getppid()会返回调用进程的父进程ID:
1 |
|