跳到主要内容

操作系统常见问题

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

进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。IPC 的方式通常有管道(包括无名管道和命名管道)、消息队列、信号量、共享存储、Socket、Streams 等。其中 Socket 和 Streams 支持不同主机上的两个进程 IPC。

管道

  1. 它是半双工的,具有固定的读端和写端;
  2. 它只能用于父子进程或者兄弟进程之间的进程的通信;
  3. 它可以看成是一种特殊的文件,对于它的读写也可以使用普通的 read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。

命名管道

  1. FIFO 可以在无关的进程之间交换数据,与无名管道不同;
  2. FIFO 有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中。

消息队列

  1. 消息队列,是消息的链接表,存放在内核中。一个消息队列由一个标识符 ID 来标识;
  2. 消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级;
  3. 消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除;
  4. 消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。

信号量

  1. 信号量(semaphore)是一个计数器。用于实现进程间的互斥与同步,而不是用于存储进程间通信数据;
  2. 信号量用于进程间同步,若要在进程间传递数据需要结合共享内存;
  3. 信号量基于操作系统的 PV 操作,程序对信号量的操作都是原子操作;
  4. 每次对信号量的 PV 操作不仅限于对信号量值加 1 或减 1,而且可以加减任意正整数;
  5. 支持信号量组。

共享内存

  1. 共享内存(Shared Memory),指两个或多个进程共享一个给定的存储区;
  2. 共享内存是最快的一种 IPC,因为进程是直接对内存进行存取。

什么是缓冲区溢出?有什么危害?

缓冲区为暂时置放输出或输入资料的内存。缓冲区溢出是指当计算机向缓冲区填充数据时超出了缓冲区本身的容量,溢出的数据覆盖在合法数据上。造成缓冲区溢出的主要原因是程序中没有仔细检查用户输入是否合理。

计算机中,缓冲区溢出会造成的危害主要有以下两点:程序崩溃导致拒绝服务和跳转并且执行一段恶意代码。

守护进程、僵尸进程和孤儿进程

守护进程

指在后台运行的,没有控制终端与之相连的进程。它独立于控制终端,周期性地执行某种任务。Linux 的大多数服务器就是用守护进程的方式实现的,如 web 服务器进程 http 等

孤儿进程

如果父进程先退出,子进程还没退出,那么子进程的父进程将变为init进程。(注:任何一个进程都必须有父进程)。

一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被 init 进程(进程号为 1)所收养,并由 init 进程对它们完成状态收集工作。

僵尸进程

如果子进程先退出,父进程还没退出,那么子进程必须等到父进程捕获到了子进程的退出状态才真正结束,否则这个时候子进程就成为僵尸进程。

设置僵尸进程的目的是维护子进程的信息,以便父进程在以后某个时候获取。这些信息至少包括进程 ID,进程的终止状态,以及该进程使用的 CPU 时间,所以当终止子进程的父进程调用 wait 或 waitpid 时就可以得到这些信息。如果一个进程终止,而该进程有子进程处于僵尸状态,那么它的所有僵尸子进程的父进程 ID 将被重置为 1(init进程)。继承这些子进程的 init 进程将清理它们(也就是说 init 进程将 wait 它们,从而去除它们的僵尸状态)。