关闭

进程相关概念

标签: 进程
327人阅读 评论(0) 收藏 举报
分类:

1、进程与程序

1、概念

程序(program)是包含了一系列信息的文件,而进程(process)是程序的一个实例。就像类与对象一样。程序中包含的信息描述了如何在运行时创建一个进程,内容有:
  1. 二进制格式标识:每个程序文件都有用来描述可执行文件格式的原信息,内核用这些信息来解释文件中的其他信息;
  2. 机器语言指令:对程序算法进行编码;
  3. 程序入口地址:标识程序开始执行时的起始指令位置;
  4. 数据:初始变量和字面常量等;
  5. 符号表及重定位表:描述程序中函数和变量的位置和名称;
  6. 共享库和动态链接信息;
  7. 其他信息:用来描述如何创建进程;
一个程序可以用来创建多个进程,就像可以对一个类可以实例化多个对象一样。而进程是由内核定义的抽象的实体,由用户内存空间和一系列内核数据结构组成。其中,用户内存空间包含了程序代码及代码使用的变量,而内核数据结构用来维护进程的状态信息。记录在内核数据结构中的信息包含许多与进程相关的标志号、虚拟内存表、打开文件的描述符表、信号传递及处理的有关信息、进程资源使用及限制、当前工作目录和大量的其他信息。

2、进程号

每个进程都有一个正数表示的进程号(PID),用来唯一标识进程。进程号可以作为各种系统调用的参数和返回值。如kill()和getpid()等。
系统调用getpid()返回调用进程的进程号,定义在<unistd.h>库中,原型如下:
pid_t getpid(void);
返回类型是pid_t,用来存储进程号。
每个进程都有一个创建自己的父进程,所有进程的始祖是init进程,因此,所有的进程构成了一棵以init进程为根的进程树。系统调用getppid()可以返回父进程的进程号。init进程号是1,调用getppid()也返回1。

2、进程内存


上图展示了进程内存的分布,可以看出内存是分为一段一段的,每一段称为“段(segment)”。一个进程内存有多个段:
  1. 文本段:包含程序机器语言指令,也叫代码段。文本段只能读不能写,这是为了防止错误指针修改代码内容。一个程序可以被用来创建多个进程,因此可以将文本段设为共享;
  2. 初始化数据段:包含显示初始化的全局变量和静态变量。当程序加载到内存时,从可执行文件中读取这些变量的值;
  3. 未初始化代码段:包含了未进行初始化的全局变量和静态变量。与初始化代码段分开的原因是,程序存储时不需要为未初始化的变量分配空间;
  4. 栈:由栈帧组成,系统会为每一个函数分配一个栈帧,用来存储局部变量、传递参数与返回结果等;
  5. 堆:是可在运行时动态进行内存分配的一块区域。
上图中标识argv和environ的地方用来存储命令行参数和环境变量。

3、虚拟内存

虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。目前,大多数操作系统都使用了虚拟内存。
虚拟内存的使用使得进程的虚拟地址空间和RAM物理地址空间隔离开,优点如下:
  1. 进程与进程、进程与内核相互隔离,所以一个进程不能修改另一个进程或内核的内存;
  2. 内存中可以容纳更多的进程,提高了CPU的使用率;
  3. 两个或更多的进程可以共享内存;
  4. 便于实现内存保护机制;
  5. 程序的编写与编译无需关注程序在RAM中的物理地址;
  6. 程序中可以很小的一部分驻留在内存中,这样加载和运行速度变快。同时,一个程序需要的内存也可以超过实际大小。

4、命令行参数

C语言中都有个main函数作为程序的入口,main函数有两个参数,int型的argc和char ** 型的argv,第一个用来存储命令行参数的个数,第二个用来存储命令行参数,每个参数是以null结尾的字符串。其中,第一个参数,即argv[0],通常是程序的名称。argv中的指针链表以NULL指针结尾。
下图展示了一个命令行参数的例子:

注意,命令行参数的局限之一就是只能被main函数使用。

5、环境列表

每一个进程都有与其相关的称之为环境列表的字符串数组,简称环境。每个字符串都以名称=值(name=value)的形式定义,可存储任何信息。我们将列表中的名称称为环境变量。
进程创建时,会继承父进程的环境副本,之后的操作互不影响彼此的环境。
下图是环境列表的数据结构,可以看到,环境列表和命令行参数很像:

在C语言中,可以使用全局变量char **environ来访问环境列表。如下面的程序打印环境变量:
#include <stdio.h>
extern char **environ;
int main(int argc,char *argv[])
{
	char **ep;
	for(ep=environ;*ep!=NULL;ep++)
		puts(*ep);
	return 0;
}
结果如下:


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:109500次
    • 积分:1970
    • 等级:
    • 排名:第19905名
    • 原创:76篇
    • 转载:8篇
    • 译文:1篇
    • 评论:21条
    博客专栏