• 【总结】操作系统的重点


    1、线程,进程,协程的区别?

    • 进程是 具有独立功能的程序的一次运行活动,是 系统进行资源分配和调度的一个独立单位。
    • 线程是 进程的一个执行单元,是CPU执行的基本单位
    • 一个进程可以有多个线程,多个线程也可以并发执行(单线程CPU 在同一时间内只能够运行一个线程,多核 CPU 可以同时调度多个线程执行)
    • 1)进程间相互独立,同一进程的各线程间共享进程中的资源。某进程内的线程在其它进程不可见
      2)调度和切换:线程上下文切换比进程上下文切换要快得多
      3)线程不能够独立执行,必须依存在进程中,由应用程序提供多个线程执行控制
    • 可以创建线程来异步处理一些计算,像Unity的Job System就可以让粒子、动画、资源加载、场景加载等等放到Worker Threads中,利用多核特性对性能进行优化。
    • 另外Unity还提供了协程来模拟多线程,将一个函数分成多个部分来顺序执行,本质是一个迭代器块,还是在主线程执行,用yield return返回
    • GPU并行计算
     
    线程执行开销小,但不利于资源的管理和保护;而进程正相反。
     
    2、哪些资源是进程共享的?
    多个进程 可以共享 进程代码段data section进程的公有数据(线程间通讯)等系统资源,可以调用同一段程序代码
     
    3、进程中的哪些资源是线程共享的?
    线程私有
    程序计数器 :每个线程都有自己独立的程序计数器,用来指示下一条指令的地址。
    虚拟机栈:即栈区,在编译期间完成分配。
    线程共享
    垃圾收集器管理的主要区域。
    方法区 :所有线程共享,存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。这个区域的内存回收目标主要是针对常量池的对象的回收和对类型的卸载。
    线程共享资源
    线程独享资源
    地址空间 data section
    程序计数器
    全局变量 global
    寄存器
    打开的文件 file fd
    子进程
    状态字
    闹铃
     
    信号及信号服务程序 signal
     
    记账信息 id
     
    4、进程通信方式
    1. 进程互斥与同步(PV)
    2. 信号signal 与 信号量semaphore
    3. 共享存储器系统(共享存储区)
    4. 消息传递系统(直接发送/信箱通信)
    5. 管道通信系统(共享文件)
    6. socket、文件锁
    全局变量则不是
    管道是半双工的,是一种固定大小的缓冲区。当管道满时,进程在写管道会被阻塞,而当管道空时,进程读管道会被阻塞
     
    5、进程同步
    在多道程序环境下,进程是并发执行的,不同进程之间存在着不同的相互制约关系(互斥和同步)。进程同步是对多个进程的执行顺序进行协调
     
    互斥争用资源,指某一资源同时只允许一个访问者对其进行访问(无法限制顺序),常用 互斥信号量 记录PV
         互斥量 mutex,相当于一把锁,保证同类进程互斥
    C#中的lock是互斥量,但用于线程间互斥
     
    同步:一个进程在某一点等待另一个进程提供信息,两进程存在直接的制约关系 。同步实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥。少数情况是指可以允许多个访问者同时访问资源。
    临界资源 一次仅允许一个进程使用的资源。
    临界区 每个进程中访问临界资源的那段程序代码   
     
    信号量S(用于同步)
    当它的值大于0时,表示当前可用资源的数量;
    当它的值小于0时,其绝对值表示等待使用该资源的进程个数。
    信号量机制-PV操作
    --wait ++signal 操作
    信号量用于 进程间或线程间,生产者消费者问题等……
     
    进程同步有哪几种机制
    • 原子操作:指不会被线程调度机制打断的操作。这种操作一旦开始,就一直运行到结束,中间不会有任何context switch(切换到另一个线程) 
    • 信号量机制:PV操作。必须有公共内存,不能用于分布式操作系统,这是它最大的弱点。
    • 自旋锁: 调用者申请的资源如果被占用,即自旋锁被已经被别的执行单元保持,则调用者一直循环在那里看是否该自旋锁的保持着已经释放了锁(比较低级)
    • 管程: 将共享变量和对它们的操作集中在一个模块中,操作系统或并发程序就由这样的模块构成。模块之间联系清晰,便于维护和修改,易于保证正确性
    • 会合:进程间直接进行相互作用, 一个进程可以调用另一个进程的入口。先到达会合处的等待后到达者 +FCFS。分布式系统可用。
    • 分布式系统: 网络上的一组计算机形成的系统。参数全为值参, 而且不可为指针。
     
    原子操作是不可分割的。在单处理器系统(UniProcessor)中,能够在单条指令中完成的操作都可以认为是" 原子操作",因为中断只能发生于指令之间
    但是,在对称多处理器(Symmetric Multi-Processor)中,由于系统中有多个处理器在独立地运行,即使能在单条指令中完成的操作也有可能受到干扰。我们以decl (递减指令)为例,这是一个典型的"读-改-写"过程,涉及两次内存访问,CPU A、B各自存到自己的寄存器处理,最后写入内存的结果可能就不正确(多核CPU一般一级缓存与二级缓存是每个核心进行分别均衡分配的,三级缓存才是多个核心一起共享的 )
     
    C++有atomic_flag,atomic<T>,atomic……略。除此之外的操作不保证是原子操作
    对于指针强制类型转换或者c++ placement new等情况,可能无法保证struct或class里的成员不跨越cacheline
     
    6、线程同步的方式有哪些?
    • 临界区Critical Section): 在任意时刻只允许一个线程对共享资源进行访问,通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。不能跨进程,只能实现线程互斥
    • 互斥量:采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个,所以可以保证公共资源不会被多个线程同时访问。
    • 信号量:它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量。
    • 事件(信号):通过通知操作的方式来保持多线程同步,还可以方便的实现多线程优先级的比较操作。
    以上Event、Semaphore、Mutex 是内核对象,能够跨进程使用
     
    7、什么是死锁
    在两个或者多个并发进程中,如果每个进程持有某种资源而又等待其它进程释放它或它们现在保持着的资源,在未改变这种状态之前都不能向前推进,称这一组进程产生了死锁。
     
    死锁产生的原因
    系统资源不足,进程推进顺序不当
     
    死锁的4个必要条件 怎么处理
    • 互斥条件:资源互斥  一个资源一次只能被一个进程使用
    • 请求与保持条件:占有并等待 一个进程因请求资源而阻塞时,对已获得资源保持不放
    • 不剥夺条件: 不可抢占  进程获得的资源,在未完全使用完之前,不能强行剥夺
    • 循环等待条件:循环等待 若干进程之间形成一种头尾相接的环形等待资源关系
    处理死锁的策略
    1)预防死锁: 破坏四个条件 资源静态分配
    2)避免死锁: 如银行家算法,而是在资源的动态分配过程中,用某种方法去防止系统进入不安全状态,从而避免发生死锁。
    3)检测和解除死锁:死锁检测算法
    4)不处理:鸵鸟算法,用于当死锁真正发生且影响系统正常运行时,才手动干预,重新启动
     
    安全状态指存在安全序列。系统在进行资源分配之前,先计算资源分配的安全性,若此次分配会导致系统进入不安全状态,则进程等待。
    存在安全序列时,就可避免死锁发生
    系统进入不安全状态(四个死锁的必要条件同时发生)未必就会产生死锁。当然,产生死锁后,系统一定处于不安全状态。 

    8、虚拟内存
    32位机中,每个进程最大2^32地址(因为指针4字节寻址),即4GB虚拟内存
    将那些当前要运行的少数页面或段先装入内存便可运行,其余部分暂留在盘上。
    当内存耗尽时,电脑会自动调用硬盘来充当内存,以缓解内存的紧张。 若计算机运行程序或操作所需的随机存储器(RAM)不足时,则Windows 会用虚拟存储器进行补偿。 它将计算机的RAM和硬盘上的临时空间组合。 当RAM运行速率缓慢时,它便将数据从RAM移动到称为“分页文件”的空间中。
     
    虚拟存储器是由硬件和操作系统自动实现存储信息调度和管理的。它的工作过程包括6个步骤:
    ①中央处理器访问主存的逻辑地址分解成组号a和组内地址b,并对组号a进行地址变换,即将逻辑组号a作为索引,查地址变换表,以确定该组信息是否存放在主存内。
    ②如该组号已在主存内,则转而执行④;如果该组号不在主存内,则检查主存中是否有空闲区,如果没有,便将某个暂时不用的组调出送往辅存,以便将这组信息调入主存。
    ③从辅存读出所要的组,并送到主存空闲区,然后将那个空闲的物理组号a和逻辑组号a登录在地址变换表中。
    ④从地址变换表读出与逻辑组号a对应的物理组号a。
    ⑤从物理组号a和组内字节地址b得到物理地址。
    ⑥根据物理地址从主存中存取必要的信息。
     
    如果程序要访问的页/段尚未调入,那么请求调入
    如果内存已满,则利用置换功能调出到盘上
     

  • 相关阅读:
    102. 教程:重装谷歌浏览器的教程
    IGBT知识普及
    [刷机资源] 荣耀8 E5 B391 V2 ROM集合 Xposed DPI调整等 N多自定义功能 Kangvip@HRT( 2017-9-28)
    ITPUB附件下载免输验证码 (实际下载地址的规则)
    花生壳内网穿透不再支持国外IP!
    golang 如何开发windows窗口界面
    golang 热重启
    强化go get命令
    go mod get go-git timeout
    golang单一职责原则接口设计例子
  • 原文地址:https://www.cnblogs.com/sols/p/8807822.html
Copyright © 2020-2023  润新知