1. 进程有那几种状态,状态转换图,及导致转换的事件

Linux面试要点_面试


  如上图所示,进程包括三种状态:就绪态、运行态和阻塞态。详细说明如下:

  注意:创建和退出不是进程的状态。阻塞和就绪的区别:阻塞是等待除CPU以外的资源,而就绪等待的是CPU资源。

  1. 就绪——执行:对就绪状态的进程,当进程调度程序按一种选定的策略从中选中一个就绪进程,为之分配了处理机后,该进程便由就绪状态变为执行状态;
  2. 执行——阻塞:正在执行的进程因发生某等待事件而无法执行,则进程由执行状态变为阻塞状态,如进程提出输入/输出请求而变成等待外部设备传输信息的状态,进程申请资源(主存空间或外部设备)得不到满足时变成等待资源状态,进程运行中出现了故障(程序出错或主存储器读写错等)变成等待干预状态等等;
  3. 阻塞——就绪:处于阻塞状态的进程,在其等待的事件已经发生,如输入/输出完成,资源得到满足或错误处理完毕时,处于等待状态的进程并不马上转入执行状态,而是先转入就绪状态,然后再由系统进程调度程序在适当的时候将该进程转为执行状态;
  4. 执行——就绪:正在执行的进程,因时间片用完而被暂停执行,或在采用抢先式优先级调度算法的系统中,当有更高优先级的进程要运行而被迫让出处理机时,该进程便由执行状态转变为就绪状态。

2. 进程和线程的区别

  进程可以认为是程序执行时的一个实例。进程是系统进行资源分配的独立实体, 且每个进程拥有独立的地址空间。一个进程无法直接访问另一个进程的变量和数据结构, 如果希望让一个进程访问另一个进程的资源,需要使用进程间通信,比如:管道,文件, 套接字等。
  一个进程可以拥有多个线程,每个线程使用其所属进程的栈空间。 线程与进程的一个主要区别是,同一进程内的多个线程会共享部分状态, 多个线程可以读写同一块内存(一个进程无法直接访问另一进程的内存)。同时, 每个线程还拥有自己的寄存器和栈,其它线程可以读写这些栈内存。
线程是进程的一个特定执行路径。当一个线程修改了进程中的资源, 它的兄弟线程可以立即看到这种变化。
以下是分点小结:

  1. 进程是系统进行资源分配的基本单位,有独立的内存地址空间; 线程是CPU调度的基本单位,没有单独地址空间,有独立的栈,局部变量,寄存器, 程序计数器等。
  2. 创建进程的开销大,包括创建虚拟地址空间等需要大量系统资源; 创建线程开销小,基本上只有一个内核对象和一个堆栈。
  3. 一个进程无法直接访问另一个进程的资源;同一进程内的多个线程共享进程的资源。
  4. 进程切换开销大,线程切换开销小;进程间通信开销大,线程间通信开销小。
  5. 线程属于进程,不能独立执行。每个进程至少要有一个线程,成为主线程

3. 线程独享那些资源,共享那些资源?

线程独享:

  1. 线程ID
  2. 上下文:包括程序计数器,栈指针,寄存器信息
  3. 栈空间
  4. errno错误码
  5. 信号屏蔽字
  6. 调度优先级

线程共享:

  1. uid(用户ID),gid(组ID)
  2. 文件描述符
  3. 堆空间
  4. 当前工作目录
  5. 信号处理方式

4. 进程控制块(task_struct)包含内容?

  task_struct是Linux内核的⼀一种数据结构,它会被装载到RAM里并且包含着进程的信息。
  每个进程都把它的信息放在 task_struct 这个数据结构里,task_struct 包含了这些内容:
  标示符 (pid): 描述本进程的唯一标示符,用来区别其他进程。
  状态 :任务状态,退出代码,退出信号等。
  优先级 :相对于其他进程的优先级。
  程序计数器:程序中即将被执行的下一条指令的地址。
  内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
  上下文数据:进程执行时处理器的寄存器中的数据。
  I/O状态信息:包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。

进程的几种通信方式

管道( pipe ):
  管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
有名管道 (named pipe) :
   有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
信号量( semophore ) :
   信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
消息队列( message queue ) :
   消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
信号 ( sinal ) :
  信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
共享内存( shared memory ) :
  共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。
套接字( socket ) :
  套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。

线程同步的几种方式及生产者消费者模型

  线程同步的方式主要有以下四种:临界区(Critical Section)、互斥量(Mutex)、信号量(Semaphore)、事件(Event)的区别。

他们的主要区别和特点如下:

  1. 临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。在任意时刻只允许一个线程对共享资源进行访问,如果有多个线程试图访问公共资源,那么在有一个线程进入后,其他试图访问公共资源的线程将被挂起,并一直等到进入临界区的线程离开,临界区在被释放后,其他线程才可以抢占。
  2. 互斥量:采用互斥对象机制。 只有拥有互斥对象的线程才有访问公共资源的权限,因为互斥对象只有一个,所以能保证公共资源不会同时被多个线程访问。互斥不仅能实现同一应用程序的公共资源安全共享,还能实现不同应用程序的公共资源安全共享
  3. 信号量:它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目
  4. 事 件: 通过通知操作的方式来保持线程的同步,还可以方便实现对多个线程的优先级比较的操作
    生产者消费者模型及源代码见收藏。