计算机知识 |
---|
操作系统 进程 |
在Linux 中,每个进程都有父进程,而所有的进程都已init进程为根,形成一个树状的结构,我们在这里讲解进程组和会话,以便以更丰富的方式管理进程
每个进程都会属于一个进程组(process group)每个进程组中可以包含多个进程。进程组会有一个进程组领导进程(process group leader )领导进程的PID 成为进程组的ID (PGID)以识别进程组
PID 为进程自身的ID , PGID为进程所在的进程组的ID PPID为进程的父进程ID
如下图
图中箭头表示父进程通过fork和exec机制产生子进程。ps和cat都是bash的子进程。进程组的领导进程的PID成为进程组ID。领导进程可以先终结。此时进程组依然存在,并持有相同的PGID,直到进程组中最后一个进程终结。
我们将一些进程归为进程组的一个重要原因是我们可以将信号发送给一个进程组。进程组中的所有进程都会收到该信号。我们会在下一部分深入讨论这一点。
fork 有两个典型的用法
- 一个进程创建一个自身的副本, 这样每个副本都可以在另一个副本执行其他任务的同事处理各自的某个操作。 这是网络服务器的典型用法,
- 一个进程想要执行另一个程序, 既然创建新进程的唯一方法是调用fork,该进程于是首先调用fork创建一个自身的副本, 然后其中一个副本(通常为子进程)调用exec 把自身替换成新的程序。 这是诸如shell之类的典型用法。
存放在硬盘上的可执行程序文件能够被Unix 执行的唯一方法是: 又一个现有进程调用六个exec函数中的某一个(当这6个函数中是哪一个被调用并不重要时, 我们往往把他们统称为exec函数)exec 把当前进程镜像替换成新的程序文件,而且该新程序通常从main函数开始执行。 进程ID并不改变。 我们称调用exec的进程为调用进程(calling process)称新执行的程序为新程序(new program)
可以先参照下图看到 内核地址空间和进程地址空间, 在32位中 进程地址空间一共4G,最高位1G 是内核空间, 所有进程都共享1G 的内核地址空间, 剩下的3G是用户地址空间
下图是说的用户地址空间
从高地址 到 低地址 顺序是:
- 栈 用户临时存放数据变量,函数调用
- 动态内存映射 mmap 动态库, 文件映射部分
- 堆 存放进程运行中被动态分配的内存段 malloc
- bss 数据段 一般用来存放未初始化的全局变量
- 初始数据段 存放程序中已经初始化的全局变量
- text数据段 用来程序可执行代码的地方
linux 内存管理有段 页 管理
进程在调用exec 系统调用时候, 会重写 进程的 text data bss stack
等各个段
达到进程重载的目的
我们经常使用fork 来生成一个字进程, 然后在调用exec 系统调用来执行新的二进制程序, 而这个exec 就是对子进程的各个段进行重写, docker 创建一个容器就是这么搞的
{% embed url="http://www.cnblogs.com/vamei/archive/2012/10/07/2713023.html" caption="" %}