操作系统(各位哥还是看图片好了....)

操作系统

进程和线程

进程

  • 进程模型,单核

    • 特点:任何一个给定瞬间仅有一个进程在运行

    • 多道程序设计:CPU在多道程序间快速切换

    • 与程序的不同

      两个进程可能恰好运行同一程序,一个进程是某种类型的一个活动,进程在内存中执行,程序在磁盘中。

      例子:
      一个人是一段程序,那他看书和开门是两个进程

  • 进程创建

    • fork

      • 父子进程有不同的地址空间

      • 父子进程有相同的内存映像,环境字符串,打开文件

      • UNIX中不可写的内存区共享,可写不共享

      • 形式

        • 写时拷贝

          • 虚拟内存独立,物理页表要修改再独立
        • 非写时拷贝

          • 虚拟内存和物理页表都独立
        • vfork()

          • 虚拟内存和物理页表都不独立
    • execve

      • 子进程执行新程序
  • 进程状态

    • 运行
    • 阻塞
    • 就绪
  • 进程实现

    • 栈段

      • 函数参数,局部变量
    • 堆段

      • 由程序员分配和释放
    • BSS

      • 存放未初始化的全局变量和静态变量
    • 数据段

      • 存放初始化的全局变量和静态变量
    • 代码段

      • 代码主体,二进制格式
  • POSIX和SYSTEM V的区别

    • POSIX

      • 在磁盘创建文件
    • SYSTEM V

      • 在内存中,断电就不可用,速度快

线程

  • 线程使用原因

    • 应用中同时发生多种活动
    • 线程轻量,易创建和销毁
    • 线程有助于应用的性能提升
  • 线程特点

    • 彼此之间无保护
    • 密切配合合作,且平等
    • 一个进程中的线程有完全一样的地址空间
    • 各自栈,寄存器,PC独立,数据段,代码段和堆段共享
  • POSIX线程

    • pthread_create

      • 创建一个线程
    • pthread_exit

      • 结束调用的线程
    • pthread_join

      • 等待特定线程退出
    • pthread_yield

      • 释放CPU来运行另一个线程
    • pthread_attr_init

      • 创建并初始化一个线程的属性结构

        • 分离状态
        • 调度策略
        • 继承性
        • 作用域
        • 栈的位置
        • 栈的大小
        • 栈末尾的警戒缓冲区大小
    • pthread_attr_destroy

      • 删除一个线程的属性结构
  • 线程实现方式

    • 用户

        • 不需要陷入内核,不需要切换上下文,调度快捷
        • 定制调度算法
        • 线程进行系统调用,阻塞整个进程

          由于内核不知道线程的存在,所以当用户线程引起阻塞时,通常会把整个进程阻塞直到磁盘I/O设备完成为止,尽管其他线程是可以运行的。

        • 一个线程开始运行,其他线程就不能运行,除非自动放弃

    • 内核

        • 内核中有线程表,创建或销毁都是针对线程表操作,线程引起的阻塞,内核可以很方便的调度
        • 直接针对线程表操作,开销大
    • 混合

  • 杂例

    • 弹出式线程

      • 一个消息到达导致系统创建一个处理该消息的线程
    • 单线程多线程化(通过模拟实现),看不太懂

进程通信

  • 竞争条件

    • 取决于进程运行时的精准时序
  • 临界区

    • 对共享资源进行访问的程序片段
  • 互斥

    • 软件算法

      • 锁变量

      • 严格轮转法

        • 忙等待

          • 等待一个变量直到出现某个值为止,Peterson的while();便是忙等待
        • 自旋锁

          • 用于忙等待的锁
      • Peterso解法

        int turn;
        int interested[N];
        void enter_region(int process)//进程0|1
        {
        int other;
        interested[process]=true;
        turn=process;
        while(turn==process&&interested[other]==true);
        }
        //临界区代码
        void leave_region(int process)//进程离开
        {
        interested[process]=false;
        }

    • 硬件

      • 屏蔽中断

        进程的切换势必会引起中断,只要在进程执行时屏蔽中断,就可以达到互斥效果,但缺陷也很明显,不是一种合适的通用互斥机制。

      • TSL指令(仅作了解,硬件实现)

  • 同步

    • 生产者-消费者问题(有界缓冲区问题)

    • 信号量S,PV操作

      • S:当信号量S小于0时,其绝对值表示系统中因请求该类资源而被阻塞的进程数目。S大于0时表示可用的临界资源数。注意在不同情况下所表达的含义不一样。当等于0时,表示刚好用完。

      • P:申请资源,S-=1,S<0,进程阻塞

        P(S)
        {
        value–;
        if(value<0)
        {
        //add this process to waiting queue
        block();//阻塞
        }
        }

      • V:释放资源,S+=1,S<=0,唤醒进程

        V(S)
        {
        value++;
        if(value<=0)
        {
        //remove a process from the waiting queue
        wakeup§;
        }
        }

      • 注意点:PV配套出现,否则会出现死锁

      • 经典案例

        • 读者-写者问题

          • 写者优先

            int read_count = 0;
            semaphore read_count_lock = 1;
            semaphore wsem = 1;
            reader(){
            wait(read_count_lock);
            read_count++;
            if(read_count==1) wait(wsem);
            signal(read_count_lock);

            READ_PROCESS();
            
            wait(read_count_lock);
            read_count--;
            if(read_count==0) signal(wsem);
            signal(read_count_lock);
            

            }
            writter(){
            wait(wsem);
            WRITE_PROCESS();
            signal(wsem);
            }
            多名读者可以同时读体现在READ_PROCESS()前后没有信号量抢锁语句
            因为写者需要wait(wsem)才能进入写过程,而只要储存区还有一名读者,wsem就被读者持有,故写者无法进行写
            当储存区没有读者时,wsem值为1,读者和写者公平地竞争wsem

          • 读者优先

            int write_count = 0,read_count = 0;
            semaphore write_count_lock = 1,read_count_lock = 1;
            semaphore wsem = 1,rsem = 1;
            semaphore readQueue = 1;

            reader(){
            wait(readQueue);
            wait(rsem);
            wait(read_count_lock);
            read_count++;
            if(read_count==1) wait(wsem);
            signal(read_count_lock);
            signal(rsem);
            signal(readQueue);

            READ_PROCESS();
            
            wait(read_count_lock);
            read_count--;
            if(read_count==0) signal(wsem);
            signal(read_count_lock);
            

            }

            writer(){
            wait(write_count_lock);
            write_count++;
            if(write_count==1) wait(rsem);
            signal(write_count_lock);

            wait(wsem);
            WRITE_PROCESS();
            signal(wsem);
            
            wait(write_count_lock);
            write_count--;
            if(write_count==0) signal(rsem);
            signal(write_count_lock);
            

            }
            最多只有一名读者在rsem上排队,每次读者释放readQueue才有一名新的读者抢rsem,与此同时第一名写者也在抢rsem
            如果写者没有抢到rsem,则每次读者计数更新后都有写者和一名读者竞争rsem
            如果写者抢到rsem,则会使后来读进程阻塞在rsem和readQueue上。当前储存区内读进程结束后,写者开始写
            因为只和一名读者竞争,所以写者的优先权得到进一步提高
            readQueue的作用在于每次和读者竞争rsem的写者只有一个,也就不存在公平竞争中当一个读者成功拿到wsem后会不断唤醒另外的读者,导致一个写者和多个读者竞争

          • 公平竞争

            int write_count = 0,read_count = 0;
            semaphore write_count_lock = 1,read_count_lock = 1;
            semaphore wsem = 1,rsem = 1;

            reader(){
            wait(rsem);
            wait(read_count_lock);
            read_count++;
            if(read_count==1) wait(wsem);
            signal(read_count_lock);
            signal(rsem);

            READ_PROCESS();
            
            wait(read_count_lock);
            read_count--;
            if(read_count==0) signal(wsem);
            signal(read_count_lock);
            

            }

            writer(){
            wait(write_count_lock);
            write_count++;
            if(write_count==1) wait(rsem);
            signal(write_count_lock);

            wait(wsem);
            WRITE_PROCESS();
            signal(wsem);
            
            wait(write_count_lock);
            write_count--;
            if(write_count==0) signal(rsem);
            signal(write_count_lock);
            

            }
            读者在rsem上排队,写者在wsem上排队。第一名写者得到rsem后即限制了读者读的行为(即后来读者在rsem上阻塞),从而使写者处于优先地位(若得不到,则该写者在rsem上阻塞,后来写者因为在write_count_lock上阻塞而无法更新write_count);第一名读者得到wsem即标志着开始读,同时”锁“住排队的写者。
            rsem和wsem的抢锁顺序在读者和写者过程中一致,避免了死锁

    • 互斥量

CPU调度

  • 批处理系统

    • FCFS:先来先服务
    • SJF:最短作业优先
    • SRJF:最短剩余时间优先
  • 交互式系统

    • 轮转调度:分配时间片
    • 优先级调度
    • 保证调度:计算CPU占有率
    • 彩票调度:比如系统掌握一种彩票,作为获奖者可以获得20ms的CPU时间
  • Linux调度器(分时系统)

    • 优先级

      • 用户空间

        • 普通任务[-20,19],数值越小,优先级越大

        • 实时任务(一定时间范围内执行),[0,99],数值越大,优先级越大

          • 硬实时
          • 软实时
      • 内核空间

        • [0,139],[0,99]实时任务,[100,139]映射为普通任务,数值越小,优先级越大

        • 优先级计算

          • static_prio,静态优先级
          • normal_prio,基于static-prio和调度策略的优先级
          • prio,动态优先级
        • 负载权重

          • nice和时间片的比例关系
    • CFS

      • 思路

        • 根据各个进程的权重分配运行时间

          • 公式一:分配给进程的运行时间 = 调度周期 * 进程权重 / 所有进程权重之和

          • 公式二:vruntime = 实际运行时间 * 1024 / 进程权重

          • 公平体现

            • virtual runtime(vruntime),它记录着进程已经运行的时间,但是并不是直接记录,而是要根据进程的权重将运行时间放大或者缩小一个比例。
            • 权重来源于一个数组,static const int prio_to_weight[40] prio_to_weight[0]=1024
      • 数据结构

        • 红黑树

          • 节点存储信息:vruntime-min_vruntime

            • 目的:防止vruntime溢出
            • 原因:vruntime存储的是unsigned long,可能会溢出,所以只需记录进程vruntime的相对大小即可,也就是对vruntime进行离散化,到达回滚效果
      • 虚拟时钟

        • 任务运行,虚拟时间增加,移到树的右边
        • 高优先级任务,虚拟时钟节奏更慢,移到右侧的速度就慢,有更多机会被调度
      • 选择下一个任务

        • 直接取缓存中红黑树的最左边节点,比查找执行更快
      • 性能

        • 在高负载的服务器性能好
        • 调度颗粒小
  • 计算公式

    • 周转时间=等待时间+执行时间
    • 响应比=周转时间/执行时间

死锁

资源

  • 可抢占资源,存储器
  • 不可抢占资源

简介

  • 条件

    • 互斥条件

    • 占有和等待条件

    • 不可抢占条件

    • 环路等待条件

      • 死锁发生时,系统中一定有由两个或两个以上的进程组成的一条环路,该环路中的每个进程都在等待下一个进程所占有的资源。
  • 建模

    • T

      • D
    • C

      • U
    • 说明:矩形表示资源,圆形表示进程

解决策略

  • 检测

    • 每种类型多个资源的检测

      • 通过矩阵,设置4个数据结构,分别为现有资源,可用资源,当前分配矩阵,请求矩阵
    • 每种类型一个资源的检测

      • 抽象成有向图,并检测是否有环,Tarjan算法
  • 恢复

    • 抢占资源
    • 回滚进程
    • 杀死进程
  • 避免

    • 前景知识

      • 安全状态
      • 不安全状态
    • 单个资源的银行家算法

      • 对每个请求进行检查,检查如果满足这一请求是否会达到安全状态
    • 多个

  • 预防

    • 互斥

      • 一切都使用假脱机技术,允许多个进程同时产生输出,但唯一真正使用的是守护进程
    • 占有和等待

      • 在开始就请求全部资源
    • 不可抢占

      • 抢占资源
    • 环路等待

      • 对资源设置优先级

杂例

  • 通信死锁

    • 超时中断
  • 活锁

    • 例子:两个人在一条路上相遇并同时给对方让路,导致双方都无法前进
  • 饥饿

    • FIFO策略解决

内存管理

重定位

  • 编译链接

  • 载入

  • 运行时(动态)

    • 进程PCB的基地址配合MMU共同完成
    • 最简单的执行逻辑:进程的逻辑地址必须处在基地址和基地址+界限地址中间,而每一个PCB中都会存储自己的基地址和界限地址,运行时再将这两个赋给CPU的寄存器

组织内存的方案

  • 位于ROM中的设备驱动程序

    • 0xFFFF
    • BIOS,基本输入输出系统
  • 用户程序

  • 位于RAM中的驱动程序

    • 0

矛盾

  • 内存空间有限

    • 解决策略

      • 交换

        • 内存碎片
        • 内存紧缩
      • 虚拟内存

        • 虚拟地址

          虚拟地址和物理地址通过MMU(内存管理单元)完成映射

        • 虚拟地址页面对应物理地址的页框

        • 页表

        • TLB(快表)加快分页

    • 适配方式

      • 位图,建立映射关系表

      • 链表

        • 首次适配:合适就可以
        • 下次:找到合适并记录位置,以便下次查找
        • 最佳:顾名思义
        • 最差
        • 快速:为常用大小维护链表
    • 缺页中断

      • 最优页面置换算法

      • 最近未使用,NRU

        设R(访问),M(修改)位,
        NUR(Not Recently Used)
        R位定期被时钟中断清零,以区分最近没被访问和被访问

      • 先进先出

      • 第二次机会

        对NRU和FIFO的优化,检查最老页面的R位,如果R位是0,则置换;R是1,则清0,并放到链表的尾端。

      • 最近最少使用,LRU

        • 代价大

          • 在链表中找到一个页面,删除它,然后把它移动到表头,费时!!!
        • 硬件实现

          • 要求硬件有计数器C,每次执行完+1,每个页表项都要有这个域。缺页中断就找值最小的那个页面。
        • 软件实现

          • 老化算法:对NRU的修改以模拟LRU
            具体:计数器右移一位,最左边插入R值
      • 工作集

        • 最近k次内存访问所使用过的页面的集合
        • R=1,当前时钟滴答中被访问过,在工作集中;R=0,与规定生存时间标准t作比较,小于等于表示在,大于表示不在,则置换。
      • 工作集时钟

        • 数据结构:循环链表
        • R=1,则R=0,其余和“工作集”相似
  • 物理地址暴露可能破坏OS

分段与分页的关系

  • 需要程序员了解

  • 是否可以超出物理存储器大小

  • 过程和数据可以被区分并分别保护

  • 大小浮动的表可以被很容易提供

  • 用户间过程共享方便

  • 好处

    • 得到更大的线性空间
    • 程序和数据被划分为逻辑独立的地址空间,且有助于共享和保护

文件系统

文件类型

  • 魔数(用于标识可执行文件)

  • 模块头(名称,日期,所有者,保护,大小)

  • 数据长度

  • 目标模块

  • BSS长度

  • 模块头

  • 入口点

  • 目标模块

  • 正文长度

  • 标志

  • 正文

  • 数据

  • 重定位位(装入内存后定位)

  • 符号表(用于调试)

文件系统的实现

  • 连续分配
  • 链表
  • FAT(File Allocation Table)(做法类似于Dijkstra的路径记录和输出)

I/O设备

显示器

  • 原理:CPU向对应外设的控制器或寄存器发送指令具体操作设备

  • 过程

    • 发出写命令,out指令
    • 向CPU发出中断
    • 读数据到内存

键盘

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值