linux内核用到了很多数据结构,这些数据结构都是为了提高某些方面的效率。

内核分配给进程的虚拟地址空间由以下内存区组成:

  • 程序的可执行代码
  • 程序的初始化数据
  • 程序的未初始化数据
  • 初始程序栈(即用户态栈)
  • 所需共享库的可执行代码和数据
  • 堆(由程序动态申请的内存)

内核和MMU(内存控制单元)协同定位虚拟地址空间在 内存中的实际物理位置

p89

进程描述符(process descriptor)task_struct类型结构,存在动态内存中,而不是在内核的内存区。

对每个进程来说,Linux都把两个不同的数据结构紧凑地存放在一个单独为进程分配的存储区域内:一个是与进程描述符相关的小数据结构thread_info(52个字节长),叫做线程描述符。另一个是内核态的进程堆栈(只需要几千个字节就够了,因为内核控制路径使用很少的栈),这块存储区域的大小通常为8192个字节。

这个两个东西紧密结合的主要好处:内核很容易从wsp寄存器的值获得当前在cpu上正在运行进程的thread_info结构的地址。即屏蔽掉esp的低13或12位有效位。

通过thread_info结构->task可以获得进程描述符的地址。

栈从末端向下增长,线程描述符驻留在这个内存区的开始

esp寄存器是CPU栈指针,用来存放栈顶单元的地址。从用户态刚切换到内核态后,进程的内核栈总是空的,因此,esp寄存器指向这个栈的顶端。

linux内核定义了list_head数据结构(双向链表)

prio_array_t数据结构//为了寻找优先级最高的新进程在cpu上运行(这里所以进程都是可运行进程,即处于 TASK_RUNNING)

//把不同优先级的进程放在不同的优先级链表中。

state 进程当前状态,由一组标志组成

进程标识符PID 顺序编号,越来越大

进程链表把所有进程的描述符链接起来。每个task_struct结构都包含一个list_head类型的tasks字段,其prev和next分别指向前面和后面的task_struct元素。

进程链表的头是init_task描述符,它是所谓的0进程或swapper进程的进程描述符。init_task的tasks.prev指向链表中最后插入的进程描述符的tasks字段。

进程0和进程1是由内核创建的,进程1(init)是所有进程的祖先。

pidhash表与链表

为了从PID找到对应的进程描述符指针。(eg kill())

如果全表扫描会很慢,所以使用散列表,冲突部分(例如同进程组的所有进程组号相同)用链表解决的方法。

4种PID,所以4个散列表。

pid结构

PID散列表

linux------深入理解linux内核的更多相关文章

  1. 理解 Linux backlog/somaxconn 内核参数

    https://jaminzhang.github.io/linux/understand-Linux-backlog-and-somaxconn-kernel-arguments/ 各参数的含义:h ...

  2. 深入理解linux网络技术内幕读书笔记(三)--用户空间与内核的接口

    Table of Contents 1 概论 1.1 procfs (/proc 文件系统) 1.1.1 编程接口 1.2 sysctl (/proc/sys目录) 1.2.1 编程接口 1.3 sy ...

  3. 读书笔记之Linux系统编程与深入理解Linux内核

    前言 本人再看深入理解Linux内核的时候发现比较难懂,看了Linux系统编程一说后,觉得Linux系统编程还是简单易懂些,并且两本书都是讲Linux比较底层的东西,只不过侧重点不同,本文就以Linu ...

  4. 【读书笔记::深入理解linux内核】内存寻址【转】

    转自:http://www.cnblogs.com/likeyiyy/p/3837272.html 我对linux高端内存的错误理解都是从这篇文章得来的,这篇文章里讲的 物理地址 = 逻辑地址 – 0 ...

  5. 【读书笔记::深入理解linux内核】内存寻址

    我对linux高端内存的错误理解都是从这篇文章得来的,这篇文章里讲的 物理地址 = 逻辑地址 – 0xC0000000:这是内核地址空间的地址转换关系. 这句话瞬间让我惊呆了,根据我的CPU的知识,开 ...

  6. 《深入理解Linux内核》 读书笔记

    深入理解Linux内核 读书笔记 一.概论 操作系统基本概念 多用户系统 允许多个用户登录系统,不同用户之间的有私有的空间 用户和组 每个用于属于一个组,组的权限和其他人的权限,和拥有者的权限不一样. ...

  7. 【深入理解Linux内核架构】第3章:内存管理

    3.1 概述 内存管理涵盖了许多领域: 内存中物理内存页的管理: 分配大块内存的伙伴系统: 分配小块内存的slab.slub.slob分配器: 分配非连续内存块的vmalloc机制: 进程的地址空间. ...

  8. 深入理解linux网络技术内幕读书笔记(七)--组件初始化的内核基础架构

    Table of Contents 1 引导期间的内核选项 2 注册关键字 3 模块初始化代码 引导期间的内核选项 linux运行用户把内核配置选项传给引导记录,然后引导记录再把选项传给内核. 在引导 ...

  9. 深入理解Linux网络技术内幕——内核基础架构和组件初始化

    引导期间的内核选项     Linux允许用户把内核配置选项传给引导记录,再有引导记录传给内核,以便对内核进行调整.     start_kernel中调用两次parse_args,用于引导期间配置用 ...

  10. 尝试理解Linux容器进程与宿主机共享内核到底是什么意思?

    背景 近期接触容器技术时,经常看到各类比较容器与虚拟机区别的文章中会提到:容器是共享宿主机的内核,而虚拟机则是拥有自己独立的内核,所以不可能在Linux上用容器运行windows,但是用虚拟机则可以. ...

随机推荐

  1. 转:oracle几组重要的常见视图-v$undostat,v$open_cursor,v$rowcache,v$session_longops,v$waitstat

    v$undostat 本视图监控当前实例中undo空间以及事务如何运行.并统计undo空间开销,事务开销以及实例可用的查询长度. V$UNDOSTAT中的常用列 Endtime:以10分钟为间隔的结束 ...

  2. postgresql 9.5 pgpool 主从复制 以及错误解决

    PostgreSQL+pgpool-II复制方案 这里不做功能的描述,只写搭建的过程和遇到的一些问题 1 系统 [root@mysqlhq ~]# cat /etc/redhat-release Ky ...

  3. Py修行路 python基础 (十三)匿名函数 与 内置函数

    一.匿名函数  1.定义: 匿名函数顾名思义就是指:是指一类无需定义标识符(函数名)的函数或子程序. 2.语法格式:lambda 参数:表达式 lambda语句中,开头先写关键字lambda,冒号前是 ...

  4. springboot成神之——log4j2的使用

    本文介绍如何在spring-boot中使用log4j2 说明 依赖 日志记录语句 log4j2配置文件 本文介绍如何在spring-boot中使用log4j2 说明 log4j2本身使用是非常简单的, ...

  5. .gitignore non-valiate

    Git忽略规则及.gitignore规则不生效的解决办法 分享到:更多19 2015-02-12    分类:Share2人评论65,215 次人浏览 在git中如果想忽略掉某个文件,不让这个文件提交 ...

  6. Python Twisted系列教程16:Twisted 进程守护

    作者:dave@http://krondo.com/twisted-daemonologie/  译者: Cheng Luo 你可以从”第一部分 Twist理论基础“开始阅读:也可以从”Twisted ...

  7. 手机发烫是为何—— App 电量测试定位方法

    为什么要做电量测试 随着移动互联网的快速发展,手机的实用性.娱乐性越来越强.日常使用中发现,安装了应用后,即使不怎么使用,电量也会消耗很快.但如果恢复出场设置充满电后,手机可以待机很长时间.真相只有一 ...

  8. leetcode728

    vector<int> selfDividingNumbers(int left, int right) { vector<int> V; for (int i = left; ...

  9. OO设计基本原则

    OO本身就是一种大的设计模式,它是随着软件规模越来越大产生出来帮助人们建模和开发的理念,生来就带着封装.继承.多态等可复用基因.为了充分发挥这些基因的功效,使用者需要遵守一定的原则,就是所谓的面向对象 ...

  10. 【转】OpenGL随笔(1)—— mipmap 详解

    注:本文使用的所有 OpenGL 函数来自 OpenGL 4.5,优先使用 DSA. 使用 mipmap 时,OpenGL 根据被映射对象的大小(单位是像素),自动决定使用纹理图的哪个分辨率级别.mi ...