面试题
1. 进程与线程的区别?(高频面试题)
1.1 概念
进程:是并发执行的程序在执行过程当中分配和管理资源
的基本单位,是一个动态概念,竞争计算机系统资源的基本单位。
线程:是进程的一个执行单元,是进程内科调度实体。比进程更小的独立运行的基本单位。线程也被称为轻量级进程。面试
一个程序至少一个进程,一个进程至少一个线程。
算法
1.2 为何会有线程?
[!NOTE]
每一个进程都有本身的地址空间,即进程空间,在网络或多用户换机下,一个服务器一般须要接收大量不肯定数量用户的并发请求,为每个请求都建立一个进程显然行不通(系统开销大响应用户请求效率低),所以操做系统中线程概念被引进。服务器
- 线程的执行过程是线性的,尽管中间会发生中断或者暂停,可是进程所拥有的资源只为改线状执行过程服务,一旦发生线程切换,这些资源须要被保护起来。
- 进程分为单线程进程和多线程进程,单线程进程宏观来看也是线性执行过程,微观上只有单一的执行过程。多线程进程宏观是线性的,微观上多个执行操做。
- 线程的改变只表明CPU的执行过程的改变,而没有发生进程所拥有的资源的变化。
1.3 进程线程的区别?
- 地址空间:同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间。
- 资源拥有:同一进程内的线程共享本进程的资源如内存、I/O、cpu等,可是进程之间的资源是独立的。
- 一个进程崩溃后,在保护模式下不会对其余进程产生影响,可是一个线程崩溃整个进程都死掉。因此多进程要比多线程健壮。
- 进程切换时,消耗的资源大,效率高。因此涉及到频繁的切换时,使用线程要好于进程。一样若是要求同时进行而且又要共享某些变量的并发操做,只能用线程不能用进程
- 执行过程:每一个独立的进程程有一个程序运行的入口、顺序执行序列和程序入口。可是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
- 线程是处理器调度的基本单位,可是进程不是。
- 二者都可并发执行。
1.4 优缺点
- 线程执行开销小,可是不利于资源的管理和保护。线程适合在SMP机器(双CPU系统)上运行。
- 进程执行开销大,可是可以很好的进行资源管理和保护。进程能够跨机器前移。
1.5 什么时候使用多进程,什么时候使用多线程?
- 对资源的管理和保护要求高,不限制开销和效率时,使用多进程。
- 要求效率高,频繁切换时,资源的保护管理要求不是很高时,使用多线程。
2. 进程有哪几种状态?
- 就绪状态:进程已得到除处理机之外的所需资源,等待分配处理机资源
- 运行状态:占用处理机资源运行,处于此状态的进程数小于等于CPU数
- 阻塞状态: 进程等待某种条件,在条件知足以前没法执行

3. 线程同步的方式及缘由?
- 互斥量:采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。由于互斥对象只有一个,因此能够保证公共资源不会被多个线程同时访问。
- 信号量:它容许同一时刻多个线程访问同一资源,可是须要控制同一时刻访问此资源的最大线程数量。
- 事件(信号):经过通知操做的方式来保持多线程同步,还能够方便的实现多线程优先级的比较操做。
4. 线程间的通讯机制?
管道(pipe)及命名管道(named pipe):管道可用于具备亲缘关系的父子进程间的通讯,有名管道除了具备管道所具备的功能外,它还容许无亲缘关系进程间的通讯;网络
- 信号(signal):信号是一种比较复杂的通讯方式,用于通知接收进程某个事件已经发生;
- 消息队列:消息队列是消息的连接表,它克服了上两种通讯方式中信号量有限的缺点,具备写权限得进程能够按照必定得规则向消息队列中添加新信息;对消息队列有读权限得进程则能够从消息队列中读取信息;
- 共享内存:能够说这是最有用的进程间通讯方式。它使得多个进程能够访问同一块内存空间,不一样进程能够及时看到对方进程中对共享内存中数据得更新。这种方式须要依靠某种同步操做,如互斥锁和信号量等;
- 信号量:主要做为进程之间及同一种进程的不一样线程之间得同步和互斥手段;
套接字:这是一种更为通常得进程间通讯机制,它可用于网络中不一样机器之间的进程间通讯,应用很是普遍。多线程
5. 守护、僵尸、孤儿进程的概念?
[!NOTE]
在操做系统领域中,孤儿进程指的是在其父进程执行完成或被终止 后仍继续运行的一类进程。并发
5.1 基本概念
在类UNIX系统中,僵尸进程是指完成执行(经过 exit 系统调用,或运行时发生致命错误或收到终止信号所致)但在操做系统的进程表中仍然有一个表项(进程控制块PCB),处于"终止状态 "的进程。函数
在一個多工的電腦做業系統中,守护进程(英语:daemon,英语发音:/ˈdiːmən/或英语发音:/ˈdeɪmən/)是一種在后台执行的电脑程序。 此类程序会被以进程的形式初始化。 守护进程程序的名称一般以字母“d”结尾:例如,syslogd就是指管理系统日志的守护进程。操作系统
我的理解:线程
通常状况下,子进程是由父进程建立,而子进程和父进程的退出是无顺序的,二者之间都不知道谁先退出。正常状况下父进程先结束会调用 wait 或者 waitpid 函数等待子进程完成再退出,而一旦父进程不等待直接退出,则剩下的子进程会被init(pid=1)进程接收,成会孤儿进程。(进程树中除了init都会有父进程)。日志
若是子进程先退出了,父进程还未结束而且没有调用 wait 或者 waitpid 函数获取子进程的状态信息,则子进程残留的状态信息( task_struct 结构和少许资源信息)会变成僵尸进程。
守护进程( daemon) 是指在后台运行,没有控制终端与之相连的进程。它独立于控制终端,一般周期性地执行某种任务 。 守护进程脱离于终端是为了不进程在执行过程当中的信息在任何终端上显示而且进程也不会被任何终端所产生的终端信息所打断 。
5.2 危害
孤儿进程结束后会被 init 进程善后,并无危害,而僵尸进程则会一直占着进程号,操做系统的进程数量有限则会受影响。
5.3 解决
通常僵尸进程的产生都是由于父进程的缘由,则能够经过 kill 父进程解决,这时候僵尸进程就变成了孤儿进程,被 init 进程接收
6. 什么是死锁?死锁产生的条件?如何避免死锁
[!NOTE]
多个进程在运行过程当中因争夺资源而形成的一种僵局。当一个进程请求资源时,若是该资源不能当即得到,那么进程就会进入等待状态。若是一个处于等待状态的进程 P1,因为所等待的资源被另外一个处于等待状态的进程 p2 所占有,而 p2 所请求的资源又被 p1 占有,这样它们所请求的资源都不会得到,两进程一直处于等待状态,造成死锁。
6.1 死锁产生的缘由?
- 由于系统资源不足。
- 进程运行推动的顺序不合适。
- 资源分配不当等。
6.2 死锁产生的条件?
- (1)互斥条件(Mutual exclusion):资源不能被共享,只能由一个进程使用。
- (2)请求与保持条件(Hold and wait):已经获得资源的进程能够再次申请新的资源。
- (3)非剥夺条件(No pre-emption):已经分配的资源不能从相应的进程中被强制地剥夺。
- (4)循环等待条件(Circular wait):系统中若干进程组成环路,该环路中每一个进程都在等待相邻进程正占用的资源。
6.3 如何避免死锁?
- (1)打破互斥条件:改造独占性资源为虚拟资源,大部分资源已没法改造。
- (2)打破不可抢占条件:当一进程占有一独占性资源后又申请一独占性资源而没法知足,则退出原占有的资源。
- (3)打破占有且申请条件:采用资源预先分配策略,即进程运行前申请所有资源,知足则运行,否则就等待,这样就不会占有且申请。
- (4)打破循环等待条件:实现资源有序分配策略,对全部设备实现分类编号,全部进程只能采用按序号递增的形式申请资源
7. 操做系统的调度算法有哪些?
[!NOTE]
FCFS(先来先服务),优先级,时间片轮转,多级反馈
- 先来先服务(FCFS):此算法的原则是按照做业到达后备做业队列(或进程进入就绪队列)的前后次序选择做业(或进程)
- 短做业优先(SJF:Shortest Process First):这种算法主要用于做业调度,它从做业后备序列中挑选所需运行时间最短的做业进入主存运行。
- **时间片轮转调度算法:当某个进程执行的时间片用完时,调度程序便终止该进程的执行,并将它送到就绪队列的末尾,等待分配下一时间片再执行。而后把处理机分配给就绪队列中新的队首进程,同时也让它执行一个时间片。这样就能够保证队列中的全部进程,在已给定的时间内,均能得到一时间片处理机执行时间。
- 高响应比优先:按照高响应比(已等待时间+要求运行时间)/要求运行时间 优先的原则,在每次选择做业投入运行时,先计算此时后备做业队列中每一个做业的响应比RP。选择最大的做业投入运行。
- 优先权调度算法:按照进程的优先权大小来调度。使高优先权进程获得优先处理的调度策略称为优先权调度算法。注意:优先数越多,优先权越小。
- 多级队列调度算法:多队列调度是根据做业的性质和类型的不一样,将就绪队列再分为若干个队列,全部的做业(进程)按其性质排入相应的队列中,而不一样的就绪队列采用不一样的调度算法。
8. 系统调用与库函数的区别?
系统调用是最底层的应用,是面向硬件的。而库函数的调用是面向开发的,至关于应用程序的API(即预先定义好的函数)接口;
各个操做系统的系统调用是不一样的,所以系统调用通常是没有跨操做系统的可移植性,而库函数的移植性良好(c库在Windows和Linux环境下均可以操做);
库函数属于过程调用,调用开销小;系统调用须要在用户空间和内核上下文环境切换,开销较大;
库函数调用函数库中的一段程序,这段程序最终仍是经过系统调用来实现的;系统调用调用的是系统内核的服务。
在全部的ANSI C编译器版本中,C库函数是相同的 |
各个操做系统的系统调用是不一样的 |
它调用函数库中的一段程序(或函数) |
它调用系统内核的服务 |
与用户程序相联系 |
是操做系统的一个入口点 |
在用户地址空间执行 |
在内核地址空间执行 |
它的运行时间属于“用户时间” |
它的运行时间属于“系统”时间 |
属于过程调用,调用开销较小 |
须要在用户空间和内核上下文环境间切换,开销较大 |
在C函数库libc中有大约300个函数 |
在UNIX中大约有90个系统调用 |
典型的C函数库调用:system fprintf malloc |
典型的系统调用:chdir fork write brk; |