linux 内核的学习

news2024/10/6 10:25:58

一、启动流程

二、进程调度

进程

进程控制块(pid)结构体

重要的信息

进程标识符   pid

状态:任务状态

优先级:相对其他进程

程序计数器:程序中即将被执行的下一条指令的地址

内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块指针

上下文环境:进程执行时处理器的寄存器的数据

i/o状态信息:包括显示的i/o请求,分配给进程的i/o设备和进程使用的文件列表

parent指针,指向该进程的父进程,children的子进程链表

 保存在进程信息的数据结构叫做task_struct,并且可以在include/linux/sched.h里找到它。所有运行在系统里的进程都以task_struct链表的形式存在内核里

struct task_struct  
{  
    volatile long state; //说明了该进程是否可以执行,还是可中断等信息  
    unsigned long flags; // flags 是进程号,在调用fork()时给出  
    int sigpending; // 进程上是否有待处理的信号  
  
     mm_segment_t addr_limit;  //进程地址空间,区分内核进程与普通进程在内存存放的位置不同  //0-0xBFFFFFFF for user-thead    //0-0xFFFFFFFF for kernel-thread  
     //调度标志,表示该进程是否需要重新调度,若非0,则当从内核态返回到用户态,会发生调度  
     volatile long need_resched;  
     int lock_depth;    //锁深度  
     long nice;       //进程的基本时间片  
  
     //进程的调度策略,有三种,实时进程:SCHED_FIFO,SCHED_RR, 分时进程:SCHED_OTHER  
     unsigned long policy;  
     struct mm_struct *mm;    //进程内存管理信息  
  
     int processor;  
     //若进程不在任何CPU上运行, cpus_runnable 的值是0,否则是1 这个值在运行队列被锁时更新  
     unsigned long cpus_runnable, cpus_allowed;  
     struct list_head run_list;   //指向运行队列的指针  
     unsigned long sleep_time;   //进程的睡眠时间  
  
     //用于将系统中所有的进程连成一个双向循环链表, 其根是init_task  
     struct task_struct *next_task, *prev_task;  
     struct mm_struct *active_mm;  
     struct list_head local_pages;      //指向本地页面        
     unsigned int allocation_order, nr_local_pages;  
     struct linux_binfmt *binfmt;      //进程所运行的可执行文件的格式  
     int exit_code, exit_signal;  
     int pdeath_signal;           //父进程终止时向子进程发送的信号  
     unsigned long personality;  
     //Linux可以运行由其他UNIX操作系统生成的符合iBCS2标准的程序  
     int did_exec:1;   
     pid_t pid;          //进程标识符,用来代表一个进程  
     pid_t pgrp;        //进程组标识,表示进程所属的进程组  
     pid_t tty_old_pgrp;      //进程控制终端所在的组标识  
     pid_t session;             //进程的会话标识  
     pid_t tgid;  
     int leader;    //表示进程是否为会话主管  
     struct task_struct *p_opptr,*p_pptr,*p_cptr,*p_ysptr,*p_osptr;  
     struct list_head thread_group;          //线程链表  
     struct task_struct *pidhash_next;    //用于将进程链入HASH表  
     struct task_struct **pidhash_pprev;  
     wait_queue_head_t wait_chldexit;      //供wait4()使用  
     struct completion *vfork_done;         //供vfork() 使用  
  
  
     unsigned long rt_priority;       //实时优先级,用它计算实时进程调度时的weight值  
  
  
     //it_real_value,it_real_incr用于REAL定时器,单位为jiffies, 系统根据it_real_value  
  
     //设置定时器的第一个终止时间. 在定时器到期时,向进程发送SIGALRM信号,同时根据  
  
     //it_real_incr重置终止时间,it_prof_value,it_prof_incr用于Profile定时器,单位为jiffies。  
  
     //当进程运行时,不管在何种状态下,每个tick都使it_prof_value值减一,当减到0时,向进程发送  
  
     //信号SIGPROF,并根据it_prof_incr重置时间.  
     //it_virt_value,it_virt_value用于Virtual定时器,单位为jiffies。当进程运行时,不管在何种  
  
     //状态下,每个tick都使it_virt_value值减一当减到0时,向进程发送信号SIGVTALRM,根据  
  
     //it_virt_incr重置初值。  
  
     unsigned long it_real_value, it_prof_value, it_virt_value;  
     unsigned long it_real_incr, it_prof_incr, it_virt_value;  
     struct timer_list real_timer;        //指向实时定时器的指针  
     struct tms times;                      //记录进程消耗的时间  
     unsigned long start_time;          //进程创建的时间  
  
     //记录进程在每个CPU上所消耗的用户态时间和核心态时间  
     long per_cpu_utime[NR_CPUS], per_cpu_stime[NR_CPUS];   
  
  
     //内存缺页和交换信息:  
  
     //min_flt, maj_flt累计进程的次缺页数(Copy on Write页和匿名页)和主缺页数(从映射文件或交换  
  
     //设备读入的页面数); nswap记录进程累计换出的页面数,即写到交换设备上的页面数。  
     //cmin_flt, cmaj_flt, cnswap记录本进程为祖先的所有子孙进程的累计次缺页数,主缺页数和换出页面数。  
  
     //在父进程回收终止的子进程时,父进程会将子进程的这些信息累计到自己结构的这些域中  
     unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap;  
     int swappable:1; //表示进程的虚拟地址空间是否允许换出  
     //进程认证信息  
     //uid,gid为运行该进程的用户的用户标识符和组标识符,通常是进程创建者的uid,gid  
  
     //euid,egid为有效uid,gid  
     //fsuid,fsgid为文件系统uid,gid,这两个ID号通常与有效uid,gid相等,在检查对于文件  
  
     //系统的访问权限时使用他们。  
     //suid,sgid为备份uid,gid  
     uid_t uid,euid,suid,fsuid;  
     gid_t gid,egid,sgid,fsgid;  
     int ngroups;                  //记录进程在多少个用户组中  
     gid_t groups[NGROUPS];      //记录进程所在的组  
  
     //进程的权能,分别是有效位集合,继承位集合,允许位集合  
     kernel_cap_t cap_effective, cap_inheritable, cap_permitted;  
  
     int keep_capabilities:1;  
     struct user_struct *user;  
     struct rlimit rlim[RLIM_NLIMITS];    //与进程相关的资源限制信息  
     unsigned short used_math;         //是否使用FPU  
     char comm[16];                      //进程正在运行的可执行文件名  
     int link_count, total_link_ count;  //文件系统信息  
  
     //NULL if no tty 进程所在的控制终端,如果不需要控制终端,则该指针为空  
     struct tty_struct *tty;  
     unsigned int locks;  
     //进程间通信信息  
     struct sem_undo *semundo;       //进程在信号灯上的所有undo操作  
     struct sem_queue *semsleeping;   //当进程因为信号灯操作而挂起时,他在该队列中记录等待的操作  
     //进程的CPU状态,切换时,要保存到停止进程的task_struct中  
     struct thread_struct thread;  
     struct fs_struct *fs;           //文件系统信息  
     struct files_struct *files;    //打开文件信息  
     spinlock_t sigmask_lock;   //信号处理函数  
     struct signal_struct *sig;   //信号处理函数  
     sigset_t blocked;                //进程当前要阻塞的信号,每个信号对应一位  
     struct sigpending pending;      //进程上是否有待处理的信号  
     unsigned long sas_ss_sp;  
     size_t sas_ss_size;  
     int (*notifier)(void *priv);  
     void *notifier_data;  
     sigset_t *notifier_mask;  
     u32 parent_exec_id;  
     u32 self_exec_id;  
  
     spinlock_t alloc_lock;  
     void *journal_info;  
};  

时间片不需要直接手动设置,操作系统的调度算法会自动分配好,我们也可以使用函数设置

优先级在创建线程的时候,会分配一个默认的优先级,我们也可以修改默认的优先级

进程的任务队列

每个进程都有一个状态,相应的状态有相应的链表来存放这个线程

就以就绪态来说,链表先是按照优先级排队,然后同一优先级就按顺序

进程的家族树

每一个进程都是进程号pid为1的init进程的后代,内核在系统启动的最后阶段启动init进程,该进程读取系统的初始脚本并且指向其他相关的程序最终完成系统启动的整个过程

进程的切换与调度

进程的调度是在内核态中实现的,主动调度内核线程直接调用schedule进行线程切换,也可以在中断处理过程的进行调度

进程创建

写时拷贝

不是直接将父进程中所有的资源全部拷贝给子进程,而是子进程与父进程共享一块地址空间,当子进程需要对某处地址空间进程修改的时候,再为其申请新的页面和拷贝,在此之间数据共享的权限为只读。

fork

fork()的实际开销就是复制父进程的页表以及给子进程创建唯一的进程描述符

vfork()不会拷贝父进程的页表,其他与fork()函数一样

linux通过clone()系统调用实现fork()

进程的销毁

当一个进程终结的时候,内核必须释放它

子进程自身使用exit()函数退出,父进程通过waitpid()函数获得子进程的退出状态

线程

线程是共享一个进程的资源,

线程在linux中实现,是将所有线程当成进程来实现的

进程有自己的独立地址空间,多个线程共有一个地址空间

    每个线程都有自己的栈区,寄存器

     多个线程共享代码区、堆区、全局数据区、打开的文件(文件描述符)都是线程共享的

线程实最小的执行单位,进程是最小的的资源分配单位

    多个线程可以抢占更多的时间片

     线程切换上下文比进程切换快

线程的创建

pthread_create

线程的退出

程和进程一样,子线程退出的时候其内核资源主要由主线程回收,线程库中提供的线程回收函叫做 pthread_join()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/719412.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

echarts 柱状体点击空白处

点击红框里的空白区域: 再data里定义的idlist变量:idList: [800, 300, 500, 400, 800, 300, 500, 400, 800, 300, 500, 400, 800, 300,500, 400, 800, 300, 500, 400,]//以下是js代码var chartDom document.getElementById(echartsOne)this.myChart echarts.init…

数据产品经理的职业发展机会

在当今的数字时代,数据产品经理已成为许多企业中不可或缺的角色。随着越来越多的企业开始将数据应用于业务决策和产品开发中,数据产品经理的需求也不断增加。因此,学习成为一名数据产品经理成为了许多人的热门选择。下面说一说关于如何学习数…

tty(imx serial)(二)

基于linux-3.14.16 基于imx分析 一、串口设备注册 注册了一个uart设备驱动,和一个平台设备驱动 先一个一个看 1、serial_imx_driver平台设备驱动 看看匹配的设备树,imx6qdl.dtsi定义了很多,我们只看一个 如上图,设备树描述了…

基于 RK3399+fpga 的 VME 总线控制器设计(二)硬件和FPGA逻辑设计

3.2 FPGA 最小系统设计 FPGA 最小系统是指可以使 FPGA 正常工作的最基本的系统,主要包括电源电 路、配置电路、时钟和复位电路。本次设计使用的 FPGA 为紫光同创的 PG2L100H, 接下来具体介绍 FPGA 最小系统各个部分的电路设计。 ( 1 &#…

RflySim平台——高可信度的无人控制系统开发、测试与评估平台

01/RflySim平台背景 智能无人系统是一个复杂系统,涉及机械、控制、计算机、通信和材料等多个领域技术,而AI无疑是开发IUS所需的关键技术之一。随着新一代人工智能兴起,我们正面临一场新的工业革命,人类创造了各种无人系统&#x…

论文解读|点云分割中用于多尺度处理的金字塔结构

原创 | 文 BFT机器人 01 论文内容 这篇论文是关于点云分割中金字塔架构的多尺度处理的详细解读。 点云数据的语义分割是自动驾驶和其他应用中的关键任务。在这项工作中,作者指出了在点云分割中移动U形结构的紧迫需求和巨大好处,并受到图像分割领域最新进…

Fleet Farm EDI 需求详解

Fleet Farm 是一家成立于1955年的美国卖场,总部位于威斯康星州。作为一个全方位的零售商,Fleet Farm 提供了广泛的商品和服务,涵盖了农业用品、家居装饰、户外用品、汽车用品、园艺用品等多个领域。他们的使命是为客户提供高品质的产品和卓越…

《阿里大数据之路》读书笔记:第二章 日志采集

第二章 日志采集 一、浏览器的页面日志采集 浏览器的页面型产品/服务的日志采集可分为两大类: 页面浏览(展现)日志采集 指一个页面被浏览器加载呈现时采集的日志 此类日志是最基础的互联网日志 此类日志是目前所有互联网产品的两大基本指…

【Linux】LVS负载均衡群集 NAT模式

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 LVS负载均衡群集 NAT模式 一、理解负载均衡群集的原理1.企业群集应用概述2.企业群集分类3.负载均衡群集架构4.负载均衡群集工作模式分析5.NAT模式6.TUN模式7.DR模式 二、LVS虚…

ESP32 BLE蓝牙服务端客户端通信

官方帮助见这里 BLE服务端命令 ATRESTORE//复位 ATBLEINIT2 //将esp32设置成蓝牙SERVER ATBLEGATTSSRVCRE //GATTS创建服务, 建议初始化后就建立GATTS, 建立连接在创建会报错 ATBLEGATTSSRVSTART //GATTS 开启全部服务。 ATBLEGATTSCHAR? //GATTS 发现服务特征 ATBLEADDR…

回收站的文件删除了怎么恢复?实用的2个方法推荐!

我一直以为回收站里的文件都是我自己删除的文件,因此没有怎么在意。但是我刚刚清空了回收站,却发现我有些重要的文件是被误删而放入回收站的,现在这些文件都被删除了,这可怎么办? 回收站中通常会存放很多我们删除的文件…

使用QT: ActiveX控件生成文件,实现在QT项目中调用.c文件

以连接的其他控件为例,控件的位数(32/64),需要和QT编译器保持一致 我在此处连接的是.h和.c文件的类接口,在QT中使用 原始接口: 1.在QT程序中添加模块 QT axcontainer2.查看COM控件的UUID 打开一个.ui文件…

Java基础-多线程JUC-生产者和消费者

1. 生产者与消费者 实现线程轮流交替执行的结果; 实现线程休眠和唤醒均要使用到锁对象; 修改标注位(foodFlag); 代码实现: public class demo11 {public static void main(String[] args) {/*** 需求&#…

java jvm TLAB是什么?指针碰撞解释,空闲列表解释

1. 对象的创建: 当Java虚拟机遇到一条字节码new指令时,首先将去检查这个指令的参数是否能在常量池中定位到 一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,那必须先执行相应的类加载过程…

SpringBoot 实现审核功能

一、审核功能实现的方式 1、普通 方案:经办时入A表,审核后从A表读取数据,然后操作目标B表; 优势:思路简单 劣势:对后端功能实行高度的嵌入;审核功能数据操作不统一 2、弹框式 方案&#x…

HummerRisk 配置 HTTPS访问

简介 HummerRisk 是开源的云原生安全平台,以非侵入的方式解决云原生的安全和治理问题。核心能力包括混合云的安全治理和云原生安全检测。 HTTPS(Hypertext Transfer Protocol Secure)是一种通过加密和身份验证来保护网络通信安全的协议。它…

ChatGPT对高等教育的可能影响与对策建议

ChatGPT来袭,将对高等教育带来哪些影响,我们又该如何应对? 对于ChatGPT,有人欢喜有人忧,不同人、不同领域评价不一。在一些人眼里,它就是天使,而在另外一些人眼里,它几乎可以说是魔…

php导出pdf

插件官网:TCPDF 博主用的是tp6框架 、tcpdf插件 composer require tecnickcom/tcpdf --ignore-platform-reqs 后面是忽略平台要求的参数 ---------------中文乱码start------------------ 关于中文乱码问题: 网上说的下载字体放入fonts 利用tools…

Linux之系统管理

系统管理 Linux中的进程和服务 计算机中,一个正在执行的程序或命令,被叫做“进程”(process)。 启动之后一直存在、常驻内存的进程,一般被称作“服务”(service) service 服务管理&#xff…

GaussDB OLTP云数据库配套工具DDM

目录 一、前言 二、DDM定义 三、DDM业务架构 四、为什么需要DDM? 五、DDM特性 六、DDM应用场景 一、前言 现在越来越多的企业应用在逐步向云平台迁移,同时这对云平台带了一个严峻的考验和挑战。但针对华为云GaussDB数据库, 我们在生态方面做了比…