底层知识2

进程管理

进程 线程 纤程的区别

进程是OS分配资源的基本单位。
线程是执行调度的基本单位。是一个进程中的不同执行路径
两个最大的区别是:线程共享进程的内存空间,没有自己的独立空间。

线程(fiber):可以理解称为线程中的线程。 是内核态的线程
为什么会有纤程呢?
在java中JVM线程的实现方式是:经过一系列的系统调用,向OS申请,然后操作系统会产生对应的线程(这种线程叫做重量级线程),这个线程会在用户态和内核态不断切换。

这样子不断的切换需要大量的系统调用,或者说是中断(int),操作系统每次执行中断会大大的降低效率,所以就产生了用户态的线程,不需要在和操作系统打交道。

纤程的优势:

  • 占用资源很少 fiber:4k 线程:1M
  • 轻量级,切换容易
  • 可以启动多个,10w+

进程:有独立的内存空间,在内核的数据结构叫做PCB(process control block ):进程描述符

进程调度

进程调度有不同的策略,主要分为:

  • 完全公平策略Completely fair Scheduler:是按照优先级分配时间片的比例,记录每个进程的执行时间,如果一个进程执行时间不到它分配的比例,则优先执行
  • 默认调度策略:FIFO 、 RR

进程分为普通进程和实时进程,对于普通进程使用CFS策略,对于实时进程,RR代表同级别的,其他的使用FIFO策略

需要注意的是:只有实时进程主动 让出或者执行完毕,普通进程才有机会运行

中断

  • 硬中断:硬件通知我有事的一种通信策略 例如敲打一次键盘
  • 软中断: int 80中断 ,也可以叫做系统调用,每次系统调用的时候,就相当于一次软中断

重点就是:往寄存器中装系统调用号(有200多个系统调用号,代表200多个函数)

下面通过汇编语言来理解软中断

;hello.asm
;write(int fd, const void *buffer, size_t nbytes)
;fd 文件描述符 file descriptor - linux下一切皆文件

section data
    msg db "Hello", 0xA
    len equ $ - msg

section .text
global _start
_start:
    mov edx, len
    mov ecx, msg
    mov ebx, 1 ;文件描述符1 std_out
    mov eax, 4 ;write函数系统调用号 4
    int 0x80

    mov ebx, 0
    mov eax, 1 ;exit函数系统调用号
    int 0x80

这里的eax、bx、cx、dx代表不同的参数。

  • ax :write 函数
  • bx:文件描述符 代表linux输出窗口的位置
  • cx:msg代表信息
  • dx:代表信息的长度

在确定了参数后,发现执行了int 0x80中断
这时候OS就会执行响应的操作,输出框就会显示msg

一个程序的执行过程,要么处于用户态要么处于内核态

内存管理

在以前的DOS时代,同一时间只能有一个进程在运行
windows可以多个进程装入内存;这个时候就会存在2个问题

  • 内存撑爆
  • 访问到别人的空间

为了解决这2个问题,诞生了现代的内存管理系统

  • 1 分页装入(解决内存撑爆)
    内存中程序分为固定大小的页框,其大小是4K,把硬盘上的程序也按照逻辑分成4k大小的块,用到哪一块,cpu就加载哪一块(硬盘到内存)。如果内存不够了,就会把最不常用的一块内存页放到swap分区–也就是著名的LRU算法

LRU算法介绍

LRU(Least Recently Used 最近最少使用)算法(leetcode146题):哈希表(保证查找操作O(1)+双向(保证左边指针指向右边)链表(保证排序操作和新增操作0(1)))
在这里插入图片描述
在这里插入图片描述


class LRUCache extends LinkedHashMap<Integer, Integer>{
    private int capacity;
    
    public LRUCache(int capacity) {
        super(capacity, 0.75F, true);
        this.capacity = capacity;
    }

    public int get(int key) {
        return super.getOrDefault(key, -1);
    }

    public void put(int key, int value) {
        super.put(key, value);
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
        return size() > capacity; 
    }
}

  • 2 虚拟地址空间(解决相互打扰问题)
    为了保证不相互影响,让进程工作在虚拟的地址空间,程序用到的空间不在是直接的物理地址而是虚拟的地址,这样A进程就永远访问不到B进程的空间

虚拟地址是很大的,64位的操作系统有2^64byte大小的寻址空间,比实际的物理空间大很多,所以站在虚拟的角度,进程是独享整个系统+cpu,虚拟空间会把程序分成一段一段的(每一段程序的权限不同),然后在段内部就是一页一页4K大小的内存页

在这里插入图片描述
内存的映射:

  • 段的基地址,表示在哪一段的内存
  • 偏移量: 表示在段的哪一个内存页

虚拟地址(线性地址)就是:段的基地址+偏移量

如何通过虚拟地址找到物理地址?
这是通过OS+MMU(内存管理单元)来映射到物理地址

内存页就可能会遇到缺页中断:需要用到的页面内存中没有(内存页还未从硬盘load到内存中),这个时候产生缺页中断,就由内核来处理并加载

cpu如何区分一个数和一条指令:
IO总线内部分为:数据、地址、控制总线 所以是指令还是数字就看从哪条线过来的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值