上次我们了解了进程管理之 task_struct结构体
http://blog.csdn.net/qq_36782456/article/details/70215396
接下来我们看看具体内容。每个进程都把他的信息存放在task_stuct的结构体中。
task_stuct的内容为:
//标识符
描述本进程的唯一标识符,用来区分其他进程
//状态
任务状态,退出代码,退出状态等
//优先级
相对于其他进程的优先级
//程序计数器
程序中即将被执行的下一条指令的地址
//内存指针
包括程序代码和进程相关数据的指针,还有其他进程相关的内存块的指针
//上下文数据
进程执行时,寄存器的数据
//i/o状态信息
包括显示的i/o请求, 分配给进程的i/o设备和被进程使用的文件列表
//记账信息
包括处理器的时间总和,使用的时钟总和
进程标识符初始:
进程id(PID),每个进程都有非负的整形表示唯一的进程ID。好比如我们的身份证一样,每个人的身份证号是唯一的.因为进程ID标示符总是唯一的,常将其用来做其他标示符的一部分以保证其唯一性,进程ID(PID)是无法在用户层修改的。调用getpid函数可以获得当前进程的PID,此函数没有参数,如果执行成功返回当前进程的PID,失败返回-1,出错原因存储于errno。
父进程id(PPID)。当前进程的父进程id。任何进程(除init进程)都是由另一个进程创建,该进程称为被创建进程的父进程,被创建的进程称为子进程,父进程ID无法在用户层修改。父进程的进程ID即为子进程的父进程ID(PPID)。用户可以通过调用getppid函数来获得当前进程的父进程ID(PPID)。此函数没有参数,如果执行成功返回当前进程的父进程ID(PPID),失败返回-1,出错原因存储于errno。
打印自己进程与父进程:
利用ps -u 指令查看进程
这里我们注意到,父进程为bash,事实上在任何命令里运行的进程的父进程都是shell。
进程内存映像:《内核在内存中如何存放可执行程序文件》
Linux下C程序生成主要由四个步骤组成: 预编译、编译、汇编、链接。编译器gcc经过 预编译、编译、汇编3个步骤将源程序文件转换成目标文件。 如果程序有多个目标文件或程序中使用了库函数,则编译器还需要将所有目标文件及所需的库文件链接起来,最后生成可执行程序。当程序执行时,操作系统将可执行程序复制到内存中。
程序转化为进程的步骤:
1.内核将程序读入内存,为程序分配内存空间
2.内核为该进程保存PID及相关状态信息
3.把进程放在运行队列中等待执行,程序转化为进程后就可以被操作系统的调度程序执行了
进程内存映像:是指内核在内存中如何存放可执行程序文件。在将程序转化为进程的过程中,操作系统将可执行程序从硬盘复制到内存中
下面看看这段代码:
1 #include <stdio.h>
2 #include <stdlib.h>
3 int g = 100,j;
4 void test
5 {
6 int a = 10;
7 int b = 20;
8 printf("test --a-- address : 0x%x\n", &a);
9 printf("test --b-- address : 0x%x\n", &b);
10 }
11 void (*p)();
12 int main
13 {
14 int c = 30;
15 int *ptemp = malloc(sizeof(int));
16 p = test;
17 printf("c ---- address : 0x%x\n", c);
18 printf("p ---- address : 0x%x\n", p);
19 printf("j ---- address : 0x%x\n", &j);
20 printf("g ---- address : 0x%x\n", &g);
21 printf("ptemp ---- address : 0x%x\n", ptemp);
22 printf("main -c--- address : 0x%x\n", &c);
23 p();
24 return 0;
25 }
-
进程映像的位置依赖于使用的内存管理方案。
-
可执行程序与进程内存映像的不同之处在于:
a. 可执行程序位于磁盘中而内存映像位于内存;
b. 可执行程序没有堆栈,因为程序被加载到内在中才会分配堆栈;
c. 可执行程序虽然也有未初始化数据段但它并不被存储在位于硬盘中的可执行文件中;
d. 可执行程序是静态的、不变的,而内在映像随着程序的执行是在动态变化的,比如数据段随着程序的执行要存储新的变量值,栈在函数调用时也是不断在变化中。
命令行参数与环境变量:
1.从命令行参数说:
int main(int argc,char * argv[],char*env[])
第一个参数int argc,表示命令行参数的个数。
第二个参数char argv[],是一个指向命令行参数的指针数组,每一参数又都是以空字符(null) 结尾的字符串。第一个字符串,亦即argv[0]指向的,(通常)是该程序的名称。argv中的指针列表以NULL指针结尾(即argv[argc]为NULL)。argv[0]包含了调用程序的名称。 每个C语言程序都必须有一个称为main的函数,作为程序启动的起点。当执行程序时,命令行参数(command-line argument)(由shell逐一解析)通过两个入参提供给main函数。
第三个参数是charenv[],它和char*argv[]相似,指向环境变量的数组。
//命令行参数为例
//查看环境变量
1 #include <stdio.h>
2 int main
3 {
4 extern char **environ;
5 int i=0;
6 for(;environ[i]!=NULL;i++)
7 {
8 printf("%s\n",environ[i]);
9 }
10 return 0;
11 }
环境变量与命令行参数存储在栈之上