Linux进程浅析(上)

3/8/2017来源:ASP.NET技巧人气:1794

linux进程浅析(上)

程序和进程 内核中的进程结构 C语言启动过程 进程终止方式 Linux下进程的查看 进程的几种状态以及相互转换

程序和进程

程序:程序就是存放在磁盘中的可执行文件 进程:程序的执行实例称为进程 进程具有独立权限和指责,如果系统中某个进程崩溃,它不会影响到其余的进程 每个进程运行在各自的虚拟地址中,进程之间可以通过由内核控制的机制和相互通讯 进程ID:每个LInux进程都一定有一个唯一的数字标识符,称为进程ID,进程ID总是一非负整数 PID;getpid(); ps -ef | more //列出所有的进程 ps -aux | more也是查看所有的进程,二者之间存在细微差别

内核中的进程结构

进程其实在内核中主要是由一个task_struct来进行控制的, 而这个结构体是在源码的sched.h头文件中去做定义的 一般这个进程的头文件存放在/usr/src/linux-headers-4.4.0-65-generic/include/linux$ 下, 有兴趣的可以看一下这个sched.h这个文件。 文件很大

C程序的启动过程

内核会启动一个特殊例程 启动例程: 在进程main函数执行之前内核会启动 该例程放置在/lib/libc.so。。。中 编译器在编译时会将启动例程编译进可执行文件中 启动例程作用: 搜集命令行参数给main函数中的argc和argv 搜集环境变了 信息构建环境 标并且传递 给main函数 登记进程终止函数

进程终止方式:

正常终止: 1:从主函数中返回 2:调用exit(标准c库函数) 3:调用_exit或_Exit(系统调用) 4:最后一个线程从其启动例程返回 5:最后一个线程调用pthread_exit 异常终止://非法操作 1:调用abort 2:接受到一个信号并终止 3:最后一个线程对取消请求做处理响应 进程返回 同常程序运行成功返回0,否则返回非0 在shell中可以查看进程返回值(echo $?)
方式区别 return exit _exit/_EXIT
是否刷新标准IO缓存
是否调用终止函数

其实可以这样进行理解一下,就是在标准库函数中的退出其实就是在系统调用的基础之上,加上了一层缓存机制,而事实上也确实是这样。所有的标准库函调用其实都是在系统调用的基础上再次封装形成的

下面通过一个代码的形式演示一下:

#include<unistd.h> #include<fcntl.h> #include<stdlib.h> #include<stdio.h> #include<string.h> void term_fun1(void){ PRintf("first term function\n"); } void term_fun2(void){ printf("second term function\n"); } void term_func3(void){ printf("third term function\n"); } int main(int argc,char *argv[]){ char buffer[1024]= "helloworld\n"; if(argc < 2){ printf("缺少参数\n"); exit(EXIT_FAILURE); } //等级进程结束的相关函数,如果进程被终止,则会调用注册的相关函数,注意函数是以栈的形式进行存储,也就是先注册后调用 //如在进程结束后,调用的先后顺序为term_func3,term_fun2,term_fun1 atexit(term_fun1); atexit(term_fun2); atexit(term_func3); FILE * file_pointer = fopen(argv[1],"w+"); if(file_pointer != NULL){ fprintf(file_pointer,buffer); //全缓存形式进行写 }else{ printf("open file error\n"); exit(0); } if(!strcmp(argv[2],"return")){ //如果匹配到return的时候,是默认会刷缓存的 return 0; }else if(!strcmp(argv[2],"exit")){ //也会默认将缓存中的东西刷到文件中 exit(0); }else if(!strcmp(argv[2],"_exit")){ //默认不会进行刷缓存的操作,是内核提供的进行终止函数 //_EXIT(0); _exit(0); }else{ printf("正常退出\n"); } fclose(file_pointer); file_pointer = NULL; return 0; }

这里的testCode是可以直接进行run的,有兴趣的可以拿过去简单跑一下,就会发现其中哪一个函数可以刷缓存,哪一个不能刷缓存,在这里就不多做解释了

Linux下进程的查看

前面提到过进程的查看其实是由ps命令来查看的,但是单纯的ps查看的仅仅只是当前的进程。 却看不到系统中运行的其他进程; ps 查看当前 进程。信息比较少 ps -ef | more //查看进程详细信息 ps -aux | more //查看进程详细信息并且包含系统资源的命令

关于这些命令还是简单演示一下吧: 使用ps命令 这里写图片描述

使用ps -ef | more命令

这里写图片描述

使用ps -aux| more命令

这里写图片描述 从上面几张图中其实可以看到很大的差别,就是ps -aux | more显示出来的信息相对更加全面一点

关于其中的显示的信息 USER 用户属主 UID 用户ID PID 进程ID STIME 启动时间 PPID 进程父进程ID CPU CPU占用的资源 MEM 内存占用 NI 进程的NICE数值,越大,表示较少占用cpu的时间 VSZ 进程虚拟大小 rss 驻留中页的多少 TTY 终端类型 STAT 当前的状态R(runing运行状态),S(等待状态),T(终止状态),Z(僵尸状态) START 启动进程的时间 TIME 运行进程所花费的时间 COMMAND 执行命令

进程的几种状态以及相互转换

进程的几种状态主要包括了:

进程创建 进程就绪 进程运行 进程阻塞(等待)

进程结束

简单通过一张图来展示一下其相互关系:

这里写图片描述

从上面的图示中我们可以看到整个状态之间的转换图,分成了创建,就绪,运行,阻塞,以及退出这几种状态,而如果真正的细分进程的状态的话,其可以划分成更多的类型状态。在这里就不去细说了。有兴趣的童鞋可以查查。

谢谢大家的观看。这已经是第二遍了。手贱,之前写的被删掉了,结果找不回来了。这些都是关于进程的一些简单了解和介绍。在后面会更深入的了解怎么创建进程,进程调度策略等。

谢谢观看。

欢迎持续访问博客