1.何为线程?何为进程?有何区别?

  • 进程:编写的代码代码只是一个存储在硬盘的静态文件,通过编译后就会生成二进制可执行文件,当运行这个可执行文件后,它会被装载到内存中,接着CPU会执行程序中的每一条指令,那么这个运行中的程序就被成为进程
  • 线程:线程是进程当中的一条执行流程。同一个进程内的多个线程之间可以共享代码段、数据段、打开的文件等资源,但每个线程各自都有一套独自的寄存器和栈,这样可以确保线程的控制流是相对独立的。

2.并发和并行有什么区别?

  • 并发:同一时间段,多个任务都在执行(单位时间内不一定同时执行);
  • 并行:单位时间内,多个任务同时执行。

3.使用线程的优缺点?

  • 线程的优点:
    • 一个进程中可以同时存在多个线程;
    • 各个线程之间可以并发的执行
    • 各个线程之间可以共享地址空间和文件等资源
  • 线程的缺点:
    • 当进程中的一个线程崩溃时,会导致所属进程的所有线程崩溃。举个例子,对于游戏的用户设计,则不应该使用多线程的方式,否则一个用户挂了,会影响其他同个进程的线程。

4.线程与进程的比较

  • 线程与进程的比较如下:
    • 进程是资源(包括内存、打开的文件等)分配的单位,线程是CPU调度的单位
    • 进程拥有一个完整的资源平台,而线程只独享必不可少的资源,如寄存器和栈;
    • 线程同样具有就绪、阻塞、执行三种基本状态,同样具有状态之间的转换关系
    • 线程能减小并发执行的时间和空间开销
  • 对于,线程能减小并发执行的时间和空间开销,体现在:
    • 线程的创建时间比进程快,因为进程在创建的过程中,还需要资源管理信息,如内存管理信息、文件管理信息,在线程创建的过程中,不会涉及这些资源管理信息,而是共享它们;
    • 线程的终止时间比进程快,因为线程释放的资源相对比进程少很多
    • 同一个进程内的线程切换比进程切换快,因为线程具有相同的地址空间(虚拟内存共享),这意味着同一个进程的线程都具有同一个页表,那么在切换的时候不需要切换页表。而对于进程之间的切换,切换的时候要把页表给切换掉,而页表的切换过程开销比较大的;
    • 由于同一进程的各线程共享内存和资源文件,那么在线程之间数据传递的时候,就不需要经过内核了,这就使得线程之间的数据交互效率更高了。

5.什么是线程的上下文切换?

线程与进程最大的区别在于:线程是调度的基本单位,而进程是资源拥有的基本单位。 所谓操作系统的任务调度,实际上的调度对象是线程,进程只是给线程提供了虚拟内存全局变量等资源。对于线程和进程,可以做如下理解:

  • 当进程只有一个线程时,可以认为进程就等于线程
  • 当进程拥有多个线程时,这些线程会共享相同的虚拟内存和全局变量等资源,这些资源在上下文切换时是不需要修改的;
  • 另外,线程也有自己的私有数据,比如栈和寄存器等,这些在上下文切换时也是需要保存的。

6.线程上下文切换的是什么?

这得看线程是不是属于同一个进程:

  • 当两个线程不是属于同一个进程,则切换的过程就跟进程上下文切换同样
  • 当两个线程是属于同一个进程时,因为虚拟内存是共享的,所以在切换时,虚拟内存这些资源就保持不动,只需要切换线程的私有数据、寄存器等不共享的数据

7.进程的状态有哪些?

进程的三种基本状态:

  • 运行态:占有CPU,并且就在CPU上执行。
  • 就绪态:已经具备运行条件,但由于没有空闲CPU,而暂时不能运行。(即CPU没有调度到它)
  • 阻塞态:因等待某一事件而不能运行。

注意:单核处理机同一时间只有一个进程处于运行态,双核则两个。

还有两个状态:

  • 创建态:进程正在被创建,系统为其初始化PCB,分配资源。
  • 终止态:进程正在从系统中撤销,回收进程的资源,撤销其PCB。 alt

8.进程间的通信方式有哪些?

  1. 管道/匿名管道(Pipes):用于具有亲缘关系的父子进程兄弟进程之间的通信。
  2. 有名管道(Names Pipes):匿名管道由于没有名字,只能用于亲缘关系的进程间通信。为了克服这个缺点,提出了有名管道。有名管道严格遵循先进先出(first in first out)。有名管道以磁盘的方式存在可以实现本机任意两个进程通信
  3. 信号(Signal):信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生
  4. 消息队列(Message Queuing):消息队列是消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识。管道和消息队列的通信数据都是先进先出的原则。与管道(无名管道:只存在于内存中的文件;有名管道:存在于实际的磁盘介质或者文件系统)不同的是消息队列存放在内核中,只有在内核重启(即,操作系统重启)或者显式地删除一个消息队列时,该消息队列才会被真正的删除。消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取,比FIFO更有优势。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。
  5. 信号量(Semaphores):信号量是一个计数器,用于多进程对共享数据的访问,信号量的意图在于进程间同步。这种通信方式主要用于解决同步相关的问题并避免竞争条件。
  6. 共享内存(Shared memory): 使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据的更新。这种方式需要依赖某种同步操作,如互斥锁和信号量等。可以说这是最有用的进程间通信方法
  7. 套接字(Sockets):此方法主要用于在客户端和服务器之间通过网络进行通信。套接字是支持TCP/IP的网络通信的基本操作单元,可以看作是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数完成通信过程。

9.进程间的调度方式有哪些?

  • 先到先服务(FCFS)调度算法:从就绪队列中选择一个最先进入该队列的进程为之分配资源,使它立即执行并一直执行到完成或者发生某件事情而被阻塞放弃占用CPU时再重新调度。
  • 短作业优化(SJF)调度算法:从就绪队列中选择一个估计运行时间最短的进程为之分配资源,使它立即执行并一直执行到完成或发生某事件而被阻塞放弃占用CPU时再重新调度。
  • 时间片轮调度算法:一种最古老,最简单,最公平且使用最广的算法,又称RR(Round robin)调度。每个进程被分配一个时间段,称作它的时间片,即该进程允许运作的时间。
  • 多级反馈队列调度算法:前面几种都有一定的局限性。如短作业优先的调度算法,仅照顾了短进程而忽略了长进程。多级反馈队列调度算法既能使高优先级的作业得到响应又能使短作业(进程)迅速完成。因而它是目前被公认的一种较好的进程调度算法,UNIX操作系统采取的便是这种调度算法。
  • 优先级调度:为每个流程分配优先级,首先执行具有最高优先级的进程,依次类推。具有相同优先级的进程以FCFS方式执行。可以根据内存要求,时间或者任何其他资源要求来确定优先级。

10.PCB都包含什么内容?

进程描述信息:

  • 进程标识符:标识各个进程,每个进程都有一个并且唯一的标识符
  • 用户标识符:进程归属的用户,用户标识符主要为共享和保护服务

进程控制和管理信息:

  • 进程当前的状态,如new、ready、running、waiting、blocked等;
  • 进程优先级:进程抢占CPU的优先级;

资源分配清单

  • 有关内存地址空间或虚拟地址空间的信息,所打开文件的列表和所时使用I/O设备信息。

CPU相关信息

  • CPU中各个寄存器的值,当进程被切换时,CPU的状态信息都会被保存在相应的PCB中,以便进程重新执行时,能从断电继续执行

11.进程的上下文切换到底是切换什么呢?

  • 进程是由内核管理和调度的,所以进程的切换只能发生在内核态。所以,进程的上下文切换不仅包含了虚拟内存、栈、全局变量等用户空间的资源,还包括了内核堆栈、寄存器等内核空间的资源

12.产生死锁的条件?

  1. 互斥使用(资源独占):一个资源每次只能给一个进程使用
  2. 占有且等待(请求和保持,部分分配):**进程在申请新的资源的同时保有对原有资源的占有; **
  3. 不可抢占(不可剥夺):资源申请者不能强行从资源占有者手中夺取资源,资源只能由占有者资源释放。
  4. 循环等待:存在一个进程等待队列{P1, P2, ..., Pn},其中P1等待P2占有的资源,P2等待P3占有的资源,..., Pn等待P1占有的资源,形成一个进程等待循环
  • 当死锁产生的时候一定会有这四个条件,有一个条件不成立都不会造成死锁。

追问1:如何避免死锁的发生?

  • 产生死锁的条件有;互斥条件、不可剥夺条件、持有并等待条件、环路等待条件
  • 那么避免死锁问题只需要破坏其中一个条件即可,最常用的并且可行的就是使用资源有序分配法,来破坏环路等待条件