加入收藏 | 设为首页 | 会员中心 | 我要投稿 百客网 - 百科网 (https://www.baikewang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Unix > 正文

unix线程切换 操作系统面试题

发布时间:2022-10-19 12:43:03 所属栏目:Unix 来源:
导读:  1. 进程和线程的区别? 2. 协程与线程的区别? 3. 并发和并行有什么区别?

  并发就是在一段时间内,多个任务都会被处理;但在某一时刻,只有一个任务在执行。单核处理器可以做到并发。比如有两个进程A和B
  1. 进程和线程的区别? 2. 协程与线程的区别? 3. 并发和并行有什么区别?
 
  并发就是在一段时间内,多个任务都会被处理;但在某一时刻,只有一个任务在执行。单核处理器可以做到并发。比如有两个进程A和B,A运行一个时间片之后,切换到B,B运行一个时间片之后又切换到A。因为切换速度足够快,所以宏观上表现为在一段时间内能同时运行多个程序。
 
  并行就是在同一时刻,有多个任务在执行。这个需要多核处理器才能完成,在微观上就能同时执行多条指令,不同的程序被放到不同的处理器上运行,这个是物理上的多个进程同时进行。
 
  4. 进程与线程的切换流程?
 
  进程切换分两步:
 
  1、切换页表以使用新的地址空间,一旦去切换上下文,处理器中所有已经缓存的内存地址一瞬间都作废了。
 
  2、切换内核栈和硬件上下文。
 
  对于linux来说,线程和进程的最大区别就在于地址空间,对于线程切换,第1步是不需要做的,第2步是进程和线程切换都要做的。
 
  因为每个进程都有自己的虚拟地址空间,而线程是共享所在进程的虚拟地址空间的,因此同一个进程中的线程进行线程切换时不涉及虚拟地址空间的转换。
 
  5. 为什么虚拟地址空间切换会比较耗时?
 
  进程都有自己的虚拟地址空间,把虚拟地址转换为物理地址需要查找页表,页表查找是一个很慢的过程,因此通常使用Cache来缓存常用的地址映射,这样可以加速页表查找,这个Cache就是TLB(translation Lookaside Buffer,TLB本质上就是一个Cache,是用来加速页表查找的)。
 
  由于每个进程都有自己的虚拟地址空间,那么显然每个进程都有自己的页表,那么当进程切换后页表也要进行切换,页表切换后TLB就失效了,Cache失效导致命中率降低,那么虚拟地址转换为物理地址就会变慢,表现出来的就是程序运行会变慢,而线程切换则不会导致TLB失效,因为线程无需切换地址空间,因此我们通常说线程切换要比较进程切换块,原因就在这里。
 
  6. 进程间通信方式有哪些?
 
  优缺点:
 
  7. 进程间同步的方式有哪些?
 
  1、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。
 
  优点:保证在某一时刻只有一个线程能访问数据的简便办法。
 
  缺点:虽然临界区同步速度很快,但却只能用来同步本进程内的线程,而不可用来同步多个进程中的线程。
 
  2、互斥量:为协调共同对一个共享资源的单独访问而设计的。互斥量跟临界区很相似,比临界区复杂,互斥对象只有一个,只有拥有互斥对象的线程才具有访问资源的权限。
 
  优点:使用互斥不仅仅能够在同一应用程序不同线程中实现资源的安全共享,而且可以在不同应用程序的线程之间实现对资源的安全共享。
 
  缺点:
 
  3、信号量:为控制一个具有有限数量用户资源而设计。它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。互斥量是信号量的一种特殊情况,当信号量的最大资源数=1就是互斥量了。
 
  优点:适用于对Socket(套接字)程序中线程的同步。
 
  缺点:
 
  4、事件: 用来通知线程有一些事件已发生,从而启动后继任务的开始。
 
  优点:事件对象通过通知操作的方式来保持线程的同步,并且可以实现不同进程中的线程同步操作。
 
  8. 线程同步的方式有哪些?
 
  1、临界区:当多个线程访问一个独占性共享资源时,可以使用临界区对象。拥有临界区的线程可以访问被保护起来的资源或代码段,其他线程若想访问,则被挂起,直到拥有临界区的线程放弃临界区为止,以此达到用原子方式操 作共享资源的目的。
 
  2、事件:事件机制,则允许一个线程在处理完一个任务后,主动唤醒另外一个线程执行任务。
 
  3、互斥量:互斥对象和临界区对象非常相似,只是其允许在进程间使用,而临界区只限制与同一进程的各个线程之间使用,但是更节省资源,更有效率。
 
  4、信号量:当需要一个计数器来限制可以使用某共享资源的线程数目时,可以使用“信号量”对象。
 
  区别:
 
  9. 线程的分类?
 
  从线程的运行空间来说,分为用户级线程(user-level thread, ULT)和内核级线程(kernel-level, KLT)
 
  内核级线程:这类线程依赖于内核,又称为内核支持的线程或轻量级进程。无论是在用户程序中的线程还是系统进程中的线程,它们的创建、撤销和切换都由内核实现。比如英特尔i5-8250U是4核8线程,这里的线程就是内核级线程
 
  用户级线程:它仅存在于用户级中,这种线程是不依赖于操作系统核心的。应用进程利用线程库来完成其创建和管理,速度比较快,操作系统内核无法感知用户级线程的存在。
 
  10. 什么是临界区,如何解决冲突?
 
  每个进程中访问临界资源的那段程序称为临界区,一次仅允许一个进程使用的资源称为临界资源。
 
  解决冲突的办法:
 
  (1)空闲让进:临界区空闲时,可以允许一个请求进入临界区的进程立即进入临界区
 
  (2)忙则等待:当已有进程进入临界区时,其他试图进入临界区的进程必须等待
 
  (3)有限等待:对请求访问的进程,应保证能在有限时间内进入临界区
 
  (4)让权等待:当进程不能进入临界区时,应立即释放处理器,防止进程“忙等”状态。
 
  11. 什么是死锁?死锁产生的条件?
 
  什么是死锁:
 
  死锁是指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进。
 
  产生死锁的原因:竞争资源和进程推进顺序非法。
 
  死锁产生的四个必要条件:(有一个条件不成立,则不会产生死锁)
 
  如何处理死锁问题
 
  常用的处理死锁的方法有:死锁预防、死锁避免、死锁检测、死锁解除、鸵鸟策略。
 
  **(1)死锁的预防:**基本思想就是确保死锁发生的四个必要条件中至少有一个不成立:
 
  (2)死锁避免:
 
  死锁预防通过约束资源请求,防止4个必要条件中至少一个的发生,可以通过直接或间接预防方法,但是都会导致低效的资源使用和低效的进程执行。而死锁避免则允许前三个必要条件,但是通过动态地检测资源分配状态,以确保循环等待条件不成立,从而确保系统处于安全状态。所谓安全状态是指:如果系统能按某个顺序为每个进程分配资源(不超过其最大值),那么系统状态是安全的,换句话说就是,如果存在一个安全序列,那么系统处于安全状态。银行家算法是经典的死锁避免的算法。
 
  (3)死锁检测:
 
  死锁预防策略是非常保守的,他们通过限制访问资源和在进程上强加约束来解决死锁的问题。死锁检测则是完全相反,它不限制资源访问或约束进程行为,只要有可能,被请求的资源就被授权给进程。但是操作系统会周期性地执行一个算法检测前面的循环等待的条件。死锁检测算法是通过资源分配图来检测是否存在环来实现,从一个节点出发进行深度优先搜索,对访问过的节点进行标记,如果访问了已经标记的节点,就表示有存在环,也就是检测到死锁的发生。
 
  (4)死锁解除:
 
  死锁解除的常用方法就是终止进程和资源抢占,回滚。所谓进程终止就是简单地终止一个或多个进程以打破循环等待,包括两种方式:终止所有死锁进程和一次只终止一个进程直到取消死锁循环为止;所谓资源抢占就是从一个或者多个死锁进程那里抢占一个或多个资源。
 
  (5)鸵鸟策略:
 
  把头埋在沙子里,假装根本没发生问题。因为解决死锁问题的代价很高,因此鸵鸟策略这种不采取任何措施的方案会获得更高的性能。当发生死锁时不会对用户造成多大影响,或发生死锁的概率很低,可以采用鸵鸟策略。大多数操作系统,包括 Unix,Linux 和 Windows,处理死锁问题的办法仅仅是忽略它。
 
  12. 进程调度策略有哪几种? 13. 进程有哪些状态?
 
  进程一共有5种状态,分别是创建、就绪、运行(执行)、终止、阻塞。
 
  进程五种状态转换图
 
  运行态→阻塞态:往往是由于等待外设,等待主存等资源分配或等待人工干预而引起的。
 
  阻塞态→就绪态:则是等待的条件已满足,只需分配到处理器后就能运行。
 
  运行态→就绪态:不是由于自身原因,而是由外界原因使运行状态的进程让出处理器,这时候就变成就绪态。例如时间片用完,或有更高优先级的进程来抢占处理器等。
 
  就绪态→运行态:系统按某种策略选中就绪队列中的一个进程占用处理器,此时就变成了运行态。
 
  14. 什么是分页?
 
  把内存空间划分为大小相等且固定的块,作为主存的基本单位。因为程序数据存储在不同的页面中,而页面又离散的分布在内存中,因此需要一个页表来记录映射关系,以实现从页号到物理块号的映射。
 
  访问分页系统中内存数据需要两次的内存访问 (一次是从内存中访问页表,从中找到指定的物理块号,加上页内偏移得到实际物理地址;第二次就是根据第一次得到的物理地址访问内存取出数据)。

  15. 什么是分段?
 
  分页是为了提高内存利用率,而分段是为了满足程序员在编写代码的时候的一些逻辑需求(比如数据共享,数据保护,动态链接等)。
 
  分段内存管理当中,地址是二维的,一维是段号,二维是段内地址;其中每个段的长度是不一样的,而且每个段内部都是从0开始编址的。由于分段管理中,每个段内部是连续内存分配,但是段和段之间是离散分配的,因此也存在一个逻辑地址到物理地址的映射关系,相应的就是段表机制。

  16. 分页和分段有什区别? 17. 什么是交换空间?
 
  操作系统把物理内存(physical RAM)分成一块一块的小内存,每一块内存被称为页(page)。当内存资源不足时,Linux把某些页的内容转移至硬盘上的一块空间上,以释放内存空间。硬盘上的那块空间叫做交换空间(swap space),而这一过程被称为交换(swapping)。物理内存和交换空间的总容量就是虚拟内存的可用容量。
 
  用途:
 
  18. 物理地址、逻辑地址、有效地址、线性地址、虚拟地址的区别?
 
  物理地址就是内存中真正的地址,它就相当于是你家的门牌号,你家就肯定有这个门牌号,具有唯一性。不管哪种地址,最终都会映射为物理地址。
 
  在实模式下,段基址 + 段内偏移经过地址加法器的处理,经过地址总线传输,最终也会转换为物理地址。
 
  但是在保护模式下,段基址 + 段内偏移被称为线性地址,不过此时的段基址不能称为真正的地址,而是会被称作为一个选择子的东西,选择子就是个索引,相当于数组的下标,通过这个索引能够在 GDT 中找到相应的段描述符,段描述符记录了段的起始、段的大小等信息,这样便得到了基地址。如果此时没有开启内存分页功能,那么这个线性地址可以直接当做物理地址来使用,直接访问内存。如果开启了分页功能,那么这个线性地址又多了一个名字,这个名字就是虚拟地址。
 
  不论在实模式还是保护模式下,段内偏移地址都叫做有效地址。有效抵制也是逻辑地址。
 
  线性地址可以看作是虚拟地址,虚拟地址不是真正的物理地址,但是虚拟地址会最终被映射为物理地址。下面是虚拟地址 -> 物理地址的映射。
 
  19. 页面替换算法有哪些?
 
  在程序运行过程中,如果要访问的页面不在内存中,就发生缺页中断从而将该页调入内存中。此时如果内存已无空闲空间,系统必须从内存中调出一个页面到磁盘对换区中来腾出空间。
 
  最好的算法是老化算法和WSClock算法。他们分别是基于 LRU 和工作集算法。他们都具有良好的性能并且能够被有效的实现。还存在其他一些好的算法,但实际上这两个可能是最重要的。
 
  20. 什么是缓冲区溢出?有什么危害?
 
  缓冲区溢出是指当计算机向缓冲区填充数据时超出了缓冲区本身的容量,溢出的数据覆盖在合法数据上。
 
  危害有以下两点:
 
  造成缓冲区溢出的主要原因是程序中没有仔细检查用户输入。
 
  21. 什么是虚拟内存?
 
  虚拟内存就是说,让物理内存扩充成更大的逻辑内存,从而让程序获得更多的可用内存。虚拟内存使用部分加载的技术,让一个进程或者资源的某些页面加载进内存,从而能够加载更多的进程,甚至能加载比内存大的进程,这样看起来好像内存变大了,这部分内存其实包含了磁盘或者硬盘,并且就叫做虚拟内存。
 
  22. 虚拟内存的实现方式有哪些?
 
  虚拟内存中,允许将一个作业分多次调入内存。釆用连续分配方式时,会使相当一部分内存空间都处于暂时或永久的空闲状态,造成内存资源的严重浪费,而且也无法从逻辑上扩大内存容量。因此,虚拟内存的实需要建立在离散分配的内存管理方式的基础上。虚拟内存的实现有以下三种方式:
 
  23. 讲一讲IO多路复用?
 
  IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程。IO多路复用适用如下场合:
 
  24. 硬链接和软链接有什么区别? 25. 中断的处理过程? 保护现场:将当前执行程序的相关数据保存在寄存器中,然后入栈。开中断:以便执行中断时能响应较高级别的中断请求。中断处理关中断:保证恢复现场时不被新中断打扰恢复现场:从堆栈中按序取出程序数据,恢复中断前的执行状态。 26. 中断和轮询有什么区别? 27. 什么是用户态和内核态?
 
  用户态和系统态是操作系统的两种运行状态:
 
  将操作系统的运行状态分为用户态和内核态,主要是为了对访问能力进行限制,防止随意进行一些比较危险的操作导致系统的崩溃,比如设置时钟、内存清理,这些都需要在内核态下完成 。
 
  28. 用户态和内核态是如何切换的?
 
  所有的用户进程都是运行在用户态的,但是我们上面也说了,用户程序的访问能力有限,一些比较重要的比如从硬盘读取数据,从键盘获取数据的操作则是内核态才能做的事情,而这些数据却又对用户程序来说非常重要。所以就涉及到两种模式下的转换,即用户态 -> 内核态 -> 用户态,而唯一能够做这些操作的只有 系统调用,而能够执行系统调用的就只有 操作系统。
 
  一般用户态 -> 内核态的转换我们都称之为 trap 进内核,也被称之为 陷阱指令(trap instruction)。
 
  29. Unix 常见的IO模型:
 
  对于一次IO访问(以read举例),数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间。所以说,当一个read操作发生时,它会经历两个阶段:
 
  正式因为这两个阶段,linux系统产生了下面五种网络模式的方案:
 
  对于这几种 IO 模型的详细说明,可以参考这篇文章:#heading-13
 
  其中,IO多路复用模型指的是:使用单个进程同时处理多个网络连接IO,他的原理就是select、poll、epoll 不断轮询所负责的所有 socket,当某个socket有数据到达了,就通知用户进程。该模型的优势并不是对于单个连接能处理得更快,而是在于能处理更多的连接。
 
  30. select、poll 和 epoll 之间的区别?
 
  (1)select:时间复杂度 O(n)
 
  select 仅仅知道有 I/O 事件发生,但并不知道是哪几个流,所以只能无差别轮询所有流,找出能读出数据或者写入数据的流,并对其进行操作。所以 select 具有 O(n) 的无差别轮询复杂度,同时处理的流越多,无差别轮询时间就越长。
 
  (2)poll:时间复杂度 O(n)
 
  poll 本质上和 select 没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个 fd 对应的设备状态, 但是它没有最大连接数的限制,原因是它是基于链表来存储的。
 
  (3)epoll:时间复杂度 O(1)
 
  epoll 可以理解为 event poll,不同于忙轮询和无差别轮询,epoll 会把哪个流发生了怎样的 I/O 事件通知我们。所以说 epoll 实际上是事件驱动(每个事件关联上 fd)的。
 
  select,poll,epoll 都是 IO 多路复用的机制。I/O 多路复用就是通过一种机制监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),就通知程序进行相应的读写操作。但 select,poll,epoll 本质上都是同步 I/Ounix线程切换,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步 I/O 则无需自己负责进行读写,异步 I/O 的实现会负责把数据从内核拷贝到用户空间。
 

(编辑:百客网 - 百科网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章