1. 操作系统特点
并发性、共享性、虚拟性、不确定性。
2. 什么是进程
- 进程是指在系统中正在运行的一个应用程序,程序一旦运行就是进程;
- 进程可以认为是程序执行的一个实例,进程是系统进行资源分配的最小单位,且每个进程拥有独立的地址空间;
- 一个进程无法直接访问另一个进程的变量和数据结构,如果希望一个进程去访问另一个进程的资源,需要使用进程间的通信,比如:管道、消息队列等
- 线程是进程的一个实体,是进程的一条执行路径;
- 比进程更小的独立运行的基本单位,线程也被称为轻量级进程,一个程序至少有一个进程,一个进程至少有一个线程;
- 进程有运行、阻塞、就绪三个基本状态;
- 进程调度算法:先来先服务调度算法、短作业优先调度算法、非抢占式优先级调度算法、抢占式优先级调度算法、高响应比优先调度算法、时间片轮转法调度算法;
3. 进程与线程的区别
- 同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间;
- 同一进程内的线程共享本进程的资源,但是进程之间的资源是独立的;
- 一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程崩溃,所以多进程比多线程健壮;
- 进程切换,消耗的资源大。所以涉及到频繁的切换,使用线程要好于进程;
- 两者均可并发执行;
- 每个独立的进程有一个程序的入口、程序出口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
4. 说⼀下 fork, wait, exec 函数
5. 进程状态转换图

- 新状态:进程已经创建
- 就绪态:进程做好了准备,准备执⾏,等待分配处理机
- 执⾏态:该进程正在执⾏;
- 阻塞态:等待某事件发⽣才能执⾏,如等待I/O完成;
- 终⽌状态
6. 子进程和父进程怎么通信?
- 在 Linux 系统中实现父子进程的通信可以采⽤
pipe()
和fork()
函数进⾏实现; - 对于⽗⼦进程,在程序运⾏时⾸先进⼊的是⽗进程,其次是⼦进程。在创建⽗⼦进程的时候程序是先运⾏创建的程序,其次在复制⽗进程创建⼦进程。 fork() 函数主要是以⽗进程为蓝本复制⼀个进程,其 ID 号和⽗进程的 ID 号不同。对于结果 fork出来的⼦进程的⽗进程 ID 号是执⾏
fork()
函数的进程的 ID 号。 - 管道:是指⽤于连接⼀个读进程和⼀个写进程,以实现它们之间通信的共享⽂件,⼜称pipe ⽂件。
- 写进程在管道的尾端写⼊数据,读进程在管道的⾸端读出数据。
7. 进程和作业的区别
作业是用户需要计算机完成某项任务而要求计算机所做工作的集合。一个作业的完成要经过作业提交、作业收容、作业执行和作业完成4个阶段。而进程是已提交完毕的作业的执行过程,是资源分配的基本单位。
两者的主要区别如下:
-
作业是用户向计算机提交任务的任务实体。在用户向计算机提交作业之后,系统将它放入外存中的作业等待队列中等待执行;
-
而进程则是完成用户任务的执行实体,是向系统申请分配资源的基本单位。任一进程,只要它被创建,总有相应的部分存在于内存中。
-
一个作业可由多个进程组成,且必须至少由一个进程组成,但一个进程不能构成多个作业。
-
作业的概念主要用在批处理系统中。像
UNIX
这样的分时系统则没有作业的概念;而进程的概念则用在几乎所有的多道程序系统中。
8. 死锁概念及产生原理
https://blog.youkuaiyun.com/guaiguaihenguai/article/details/80303835
-
概念: 多个并发进程因争夺系统资源而产生相互等待的现象。
-
原理: 当一组进程中的每个进程都在等待某个事件发生,而只有这组进程中的其他进程才能触发该事件,这就称这组进程发生了死锁。
本质原因:
1)、系统资源有限。
2)、进程推进顺序不合理。 -
死锁产生的4个必要条件
1、互斥: 某种资源一次只允许一个进程访问,即该资源一旦分配给某个进程,其他进程就不能再访问,直到该进程访问结束。
2、占有且等待: 一个进程本身占有资源(一种或多种),同时还有资源未得到满足,正在等待其他进程释放该资源。
3、不可抢占: 别人已经占有了某项资源,你不能因为自己也需要该资源,就去把别人的资源抢过来。
4、循环等待: 存在一个进程链,使得每个进程都占有下一个进程所需的至少一种资源。当以上四个条件均满足,必然会造成死锁,发生死锁的进程无法进行下去,它们所持有的资源也无法释放。这样会导致CPU的吞吐量下降。所以死锁是会浪费系统资源和影响计算机的使用性能的。那么,解决死锁问题就是相当有必要的了。
9. 避免死锁的方法
死锁预防 ----- 确保系统永远不会进入死锁状态
产生死锁需要四个条件,那么,只要这四个条件中至少有一个条件得不到满足,就不可能发生死锁了。由于互斥条件是非共享资源所必须的,不仅不能改变,还应加以保证,所以,主要是破坏产生死锁的其他三个条件。
- 破坏“占有且等待”条件
- 方法1:所有的进程在开始运行之前,必须一次性地申请其在整个运行过程中所需要的全部资源。
优点:简单易实施且安全。
缺点:因为某项资源不满足,进程无法启动,而其他已经满足了的资源也不会得到利用,严重降低了资源的利用率,造成资源浪费。
使进程经常发生饥饿现象。 - 方法2:该方法是对第一种方法的改进,允许进程只获得运行初期需要的资源,便开始运行,在运行过程中逐步释放掉分配到的已经使用完毕的资源,然后再去请求新的资源。这样的话,资源的利用率会得到提高,也会减少进程的饥饿问题。
- 方法1:所有的进程在开始运行之前,必须一次性地申请其在整个运行过程中所需要的全部资源。
- 破坏“不可抢占”条件
当一个已经持有了一些资源的进程在提出新的资源请求没有得到满足时,它必须释放已经保持的所有资源,待以后需要使用的时候再重新申请。这就意味着进程已占有的资源会被短暂地释放或者说是被抢占了。
该种方法实现起来比较复杂,且代价也比较大。释放已经保持的资源很有可能会导致进程之前的工作实效等,反复的申请和释放资源会导致进程的执行被无限的推迟,这不仅会延长进程的周转周期,还会影响系统的吞吐量。 - 破坏“循环等待”条件
可以通过定义资源类型的线性顺序来预防,可将每个资源编号,当一个进程占有编号为i的资源时,那么它下一次申请资源只能申请编号大于i的资源。
避免死锁 ----- 在使用前进行判断,只允许不会产生死锁的进程申请资源
死锁避免是利用额外的检验信息,在分配资源时判断是否会出现死锁,只在不会出现死锁的情况下才分配资源。
两种避免办法:
- 如果一个进程的请求会导致死锁,则不启动该进程
- 如果一个进程的增加资源请求会导致死锁 ,则拒绝该申请。
避免死锁的具体实现通常利用银行家算法。