Linux中的进程

简介:

说进程之前要先说一下程序,相信大家都知道什么是程序,程序就是一个可执行文件,是一堆指令的集合。相对而言程序是静态的。而运行起来的程序就是进程,是动态的,是程序执行的过程。程序可以运行多次比如QQ可以启动多个,但是每一个都会在内存中有独立的隔离空间用于装载程序代码和数据。


我们通过ps命令可以查看Linux系统中当前运行的进程

1
ps  -aux

wKiom1gaosLw7WIXAACiReMMKes324.jpg-wh_50

具体字段请看 Linux系统的监控命令

这里面每一行都是一个进程,PID是进程号,后面的COMMAND这是具体进程或者说是程序名称。第一行永远都是PID 1的系统init进程,这个是开机内核创建的,它会一直运行直到关机,在它产生的初期是在内核态运行,然后通过系统调用,执行/sbin/init程序,从内核态切换到用户态。以后所有的用户进程都是由这个进程派生出来,它是所有用户进程的父进程,也就是说Linux内核并不直接建立用户进程。

那用户运行程序是怎么变成进程的呢?其实都是init进程通过调用fork函数复制一个自己,然后去exec最终要执行的程序。


1
top  #默认按照进程来查看

Snip20171215_108.png

1
top  -H   #按照线程来查看

Snip20171215_109.png

1
top  -H -p PID   #查看进程中跑了多少线程,其实也就是这个进程派生出来的线程

Snip20171215_111.png


关于fork:

fork的作用就是复制一个与自己一样的进程,新进程的变量、参数等都和原来的一样,但是它是一个全新的进程,并且作为原来进程的子进程。

可是通常情况下复制了自己以后就马上执行exec函数集合,调用可执行程序来取代调用该执行程序的进程内容,这就会导致原来复制的数据都白费了。所以在fork复制的时候采用了写时复制技术,也就是新的子进程和父进程都有独立的虚拟内存地址,不过这个虚拟地址都指向相同的物理地址,这就保证了它们有独立的逻辑空间,如果子进程需要修改数据的时候,在为其分配独立的物理空间,然后在把数据复制过去。但是要注意它并不是所有的东西都是用到才复制,比如虚拟地址空间结构(mm结构)、父进程的页表信息都是实实在在复制过去的,因为任何进程都是task_struct结构的实例。

所以fork就是复制一个和自己一样的进程并作为自己的子进程存在,然后由子进程去调用真正需要执行的程序。这就要用到exec函数集合。

还有一个叫做vfork,只要是跟内存有关的东西都不复制了,父子进程内存完全共享。为了避免共同操作同一个栈,当子进程生成以后,父进程就被挂起,直到子进程调用了exec函数并有了自己独立的空间或者子进程退出。如果使用vfork然后马上执行exec的话效率会比用fork要高。和fork相比,vfork节省的最大开销就是对页表的拷贝。

说明:进程都是task_struct这个数据结构的实例,这个也被称为进程描述符它记录了进程的上下文,其中有一个叫做内存描述符的数据结构(mm_struct)它描述了进程地址空间的所有信息,它包括代码段、数据段等。每个进程都有自己独立的mm_struct。即使是fork一个进程,子进程也有独立的task_struct并且有独立的mm_struct,只是它的虚拟地址空间映射到了父进程的物理地址空间而已,如果是vfork则完全不用,父子使用相同的虚拟地址空间,当然也就共享同样的物理地址空间。


fork()函数的返回值说明:

返回值
说明
PID值
说明当前在父进程中
0
说明当前在子进程中
负值
出现错误


关于exec函数集合:

exec函数集合的作用就是根据指定的文件名找到可执行文件(使用系统环境变量或者接收一个传递过来的环境变量),并用这个可执行文件取代调用进程(调用进程就是调用该exec函数集的进程,理解为上面提到的子进程)的内容。

exec函数执行成功后不会返回信息,因为调用进程(子进程)的实体包括代码、数据和堆栈都是存在的,只是被新的可执行程序所取代,只有进程ID还是和原来一样(子进程和父进程的ID可是不同的,fork一个进程就会为其分配一个独立的ID号),你可以理解为把一个程序装入到子进程中,所以不能算是全新的创建;但是如果执行失败会返回-1.


exec函数集合,如下:

arg为列表参数

int execl(const char *path, const char *arg, ...);    path是可执行程序的完整路径

int execlp(const char *file, const char *arg, ...);   file是可执行程序的文件名,无论是path还是file都会自动使用系统当前环境变量

int execle(const char *path, const char *arg, ..., char * const envp[]); envp是接收自定义的环境变量来找可执行文件

arg为数组参数

int execv(const char *path, char *const argv[]);

int execvp(const char *file, char *const argv[]);

int execve(const char *path, char *const argv[], char *const envp[]);  envp是接收自定义的环境变量来找可执行文件

上面只有execve是真正会被执行的,其他都是经过了不同封装因为传递的参数会有不同,但是他们最终也是要执行execve的。

再说回进程,当子进程退出时,会通知父进程,让父进程来清理自己的内存空间,并在内核里留下自己的退出信息,如果退出正常完成该code就是0,如果不正常就是大于0的整数。父进程调用wait函数清理子进程使用的内存空间,并且可以获取到子进程的退出信息。如果子进程没有退出,而父进程退出了呢?那么子进程就会被init进程所接管,成为子进程的新父进程,而之前退出的父进程是init进程的子进程,所以init就会调用wait函数去清理其使用的内存然后获取退出信息。

wKioL1ga3azhKqwjAACJ_mxkizI407.jpg-wh_50

从上图我们可以看到进程的树形结构init在最顶层。


Linux中到底有没有线程概念呢?如果你理解的线程是Windows平台下的那种线程的话,那在Linux中则没有。确切的说Linux有的就是进程,而没有真正的线程,它的线程其实就是一通特殊的进程而已。fork出来的进程你也可以说它是线程,不过跟父进程比,它是更加轻量级的。那Linux中的线程库是干嘛的呢?那个只是用来模拟线程操作而已。




      本文转自linuxjavachen  51CTO博客,原文链接:http://blog.51cto.com/littledevil/1868967,如需转载请自行联系原作者





相关文章
|
7天前
|
算法 Linux 调度
深入理解Linux操作系统的进程管理
本文旨在探讨Linux操作系统中的进程管理机制,包括进程的创建、执行、调度和终止等环节。通过对Linux内核中相关模块的分析,揭示其高效的进程管理策略,为开发者提供优化程序性能和资源利用率的参考。
29 1
|
2月前
|
资源调度 Linux 调度
Linux c/c++之进程基础
这篇文章主要介绍了Linux下C/C++进程的基本概念、组成、模式、运行和状态,以及如何使用系统调用创建和管理进程。
43 0
|
2天前
|
SQL 运维 监控
南大通用GBase 8a MPP Cluster Linux端SQL进程监控工具
南大通用GBase 8a MPP Cluster Linux端SQL进程监控工具
|
10天前
|
运维 监控 Linux
Linux操作系统的守护进程与服务管理深度剖析####
本文作为一篇技术性文章,旨在深入探讨Linux操作系统中守护进程与服务管理的机制、工具及实践策略。不同于传统的摘要概述,本文将以“守护进程的生命周期”为核心线索,串联起Linux服务管理的各个方面,从守护进程的定义与特性出发,逐步深入到Systemd的工作原理、服务单元文件编写、服务状态管理以及故障排查技巧,为读者呈现一幅Linux服务管理的全景图。 ####
|
1月前
|
缓存 监控 Linux
linux进程管理万字详解!!!
本文档介绍了Linux系统中进程管理、系统负载监控、内存监控和磁盘监控的基本概念和常用命令。主要内容包括: 1. **进程管理**: - **进程介绍**:程序与进程的关系、进程的生命周期、查看进程号和父进程号的方法。 - **进程监控命令**:`ps`、`pstree`、`pidof`、`top`、`htop`、`lsof`等命令的使用方法和案例。 - **进程管理命令**:控制信号、`kill`、`pkill`、`killall`、前台和后台运行、`screen`、`nohup`等命令的使用方法和案例。
120 4
linux进程管理万字详解!!!
|
15天前
|
缓存 算法 Linux
Linux内核的心脏:深入理解进程调度器
本文探讨了Linux操作系统中至关重要的组成部分——进程调度器。通过分析其工作原理、调度算法以及在不同场景下的表现,揭示它是如何高效管理CPU资源,确保系统响应性和公平性的。本文旨在为读者提供一个清晰的视图,了解在多任务环境下,Linux是如何智能地分配处理器时间给各个进程的。
|
26天前
|
存储 运维 监控
深入Linux基础:文件系统与进程管理详解
深入Linux基础:文件系统与进程管理详解
69 8
|
23天前
|
网络协议 Linux 虚拟化
如何在 Linux 系统中查看进程的详细信息?
如何在 Linux 系统中查看进程的详细信息?
46 1
|
23天前
|
Linux
如何在 Linux 系统中查看进程占用的内存?
如何在 Linux 系统中查看进程占用的内存?
|
1月前
|
算法 Linux 定位技术
Linux内核中的进程调度算法解析####
【10月更文挑战第29天】 本文深入剖析了Linux操作系统的心脏——内核中至关重要的组成部分之一,即进程调度机制。不同于传统的摘要概述,我们将通过一段引人入胜的故事线来揭开进程调度算法的神秘面纱,展现其背后的精妙设计与复杂逻辑,让读者仿佛跟随一位虚拟的“进程侦探”,一步步探索Linux如何高效、公平地管理众多进程,确保系统资源的最优分配与利用。 ####
69 4