当前位置: 首页 > news >正文

操作系统学习笔记——进程间通信方式详解及优缺点对比,僵尸进程,孤儿进程,守护进程

进程间通信方式详解及优缺点对比

    • 一、常见进程间通信方式及解释
      • 1. 管道(Pipe)
        • ✅ 定义:
        • ✅ 特点:
        • ✅ 优点:
        • ❌ 缺点:
      • 2. 命名管道(Named Pipe / FIFO)
        • ✅ 定义:
        • ✅ 优点:
        • ❌ 缺点:
      • 3. 流管道(s_pipe)
        • ✅ 定义:
        • ✅ 优点:
        • ❌ 缺点:
      • 4. 消息队列(Message Queue)
        • ✅ 定义:
        • ✅ 优点:
        • ❌ 缺点:
      • 5. 信号量(Semaphore)
        • ✅ 定义:
        • ✅ 优点:
        • ❌ 缺点:
      • 6. 信号(Signal)
        • ✅ 定义:
        • ✅ 优点:
        • ❌ 缺点:
      • 7. 共享内存(Shared Memory)
        • ✅ 定义:
        • ✅ 优点:
        • ❌ 缺点:
      • 8. 套接字(Socket)
        • ✅ 定义:
        • ✅ 优点:
        • ❌ 缺点:
    • 二、通信方式对比表(总结)
    • 三、进程间通信方式怎么选?
    • 四、线程间同步机制有哪些?
      • 1. 临界区(Critical Section)
      • 2. 互斥量(Mutex)
      • 3. 信号量(Semaphore)
      • 4. 事件(Event)
    • 用户线程(User Thread)是啥?
      • 特点:
    • 内核线程(Kernel Thread)是啥?
      • 特点:
    • 用户线程和内核线程的区别
    • 两者优缺点总结
      • 用户线程的优点:
      • 用户线程的缺点:
      • 内核线程的优点:
      • 内核线程的缺点:
    • 什么是僵尸进程、孤儿进程、守护进程?
      • 僵尸进程(Zombie Process)
      • 如何避免僵尸进程?
      • 孤儿进程(Orphan Process)
      • 守护进程(Daemon)
    • 僵尸进程、孤儿进程、守护进程的对比

一、常见进程间通信方式及解释

1. 管道(Pipe)

✅ 定义:

管道是最基本的进程间通信方式,允许一个进程将数据传输给另一个进程。

✅ 特点:
  • 半双工通信:数据只能单向传输;
  • 有亲缘限制:只能用于父子进程之间。
✅ 优点:
  • 简单易用,适合基础场景。
❌ 缺点:
  • 不能用于无关进程;
  • 传输方向单一;
  • 通信缓冲区有限,速度较慢。

2. 命名管道(Named Pipe / FIFO)

✅ 定义:

命名管道为普通管道加了“名字”,因此可以让无亲缘关系的进程通信

✅ 优点:
  • 可用于无亲缘关系的进程间通信;
  • 仍然是管道模型,使用简单。
❌ 缺点:
  • 通信效率仍不高;
  • 适合小量、频繁的数据传输。

3. 流管道(s_pipe)

✅ 定义:

流管道是一种全双工管道,突破了传统管道“只能单向传输”的限制。

✅ 优点:
  • 支持双向通信,更灵活。
❌ 缺点:
  • 实现复杂度稍高;
  • 使用范围仍有限。

4. 消息队列(Message Queue)

✅ 定义:

消息队列是一个内核维护的消息链表,进程可以写入和读取消息,彼此通信。

✅ 优点:
  • 支持格式化数据;
  • 通信无需同步机制;
  • 可用于任意进程之间。
❌ 缺点:
  • 消息长度和数量有限;
  • 复制数据时消耗 CPU;
  • 不适合大数据或高频传输。

5. 信号量(Semaphore)

✅ 定义:

信号量不是用来传数据,而是用来协调多个进程/线程对共享资源的访问

✅ 优点:
  • 常用于同步控制
  • 多进程/多线程环境下非常实用。
❌ 缺点:
  • 不适合传递复杂数据
  • 实现需要理解同步机制。

6. 信号(Signal)

✅ 定义:

信号是操作系统中用来通知进程发生某些事件的一种机制。

✅ 优点:
  • 通知机制灵活;
  • 能跨进程、跨线程使用。
❌ 缺点:
  • 通信内容简单,仅是“通知”;
  • 响应处理较复杂。

7. 共享内存(Shared Memory)

✅ 定义:

多个进程通过访问同一块内存区域来实现数据交换。

✅ 优点:
  • 通信速度极快,无须复制数据;
  • 适合大量数据、高频传输
  • 可被多个进程共享。
❌ 缺点:
  • 需要加锁机制(如信号量)防止竞争;
  • 使用稍复杂,需要同步控制。

8. 套接字(Socket)

✅ 定义:

套接字是一种通用通信机制,甚至可以用于不同主机之间的数据传输(例如分布式系统)。

✅ 优点:
  • 支持网络通信
  • 可用于远程或不同机器的进程通信;
  • 支持 TCP/UDP 协议,灵活强大。
❌ 缺点:
  • 实现相对复杂;
  • 通信效率不如共享内存。

二、通信方式对比表(总结)

通信方式是否支持无亲缘进程是否支持网络通信是否双向通信速度是否传数据是否同步控制
管道
命名管道
流管道否(通常)一般
消息队列一般
信号量
信号一般否(通知)
共享内存
套接字一般需控制

三、进程间通信方式怎么选?

  • 频繁、小量通信 → 用 PIPEFIFO
  • 大量数据、高频访问共享内存 + 信号量
  • 多机器/分布式系统通信Socket
  • 仅做同步控制,不传数据信号量信号

四、线程间同步机制有哪些?

除了进程之间的通信,线程之间也常常需要同步互斥控制,避免资源冲突。最基础的4种机制如下:

1. 临界区(Critical Section)

  • 适用于保护同一进程内的共享资源;
  • 快速、适合控制数据访问;
  • 在任何时刻只能有一个线程进入。

2. 互斥量(Mutex)

  • 类似临界区,但可用于跨进程通信
  • 实现对共享资源的互斥访问;
  • 拥有互斥量的线程才能访问资源。

3. 信号量(Semaphore)

  • 可允许多个线程同时访问资源;
  • 常用于有限资源控制(如连接池、任务队列等);
  • 支持访问数的限制。

4. 事件(Event)

  • 用于线程间通知机制
  • 可用于唤醒其他线程执行某些任务;
  • 适合处理异步任务依赖。

好的,下面我会以面向小白、通俗易懂的方式,将“内核线程 vs 用户线程 + 僵尸进程、孤儿进程、守护进程”整理为一篇结构清晰、内容详实、适合 CSDN 发布的文档。文中将包含大量示意、比喻、易懂的讲解,帮助新手快速掌握知识。

用户线程(User Thread)是啥?

用户线程,顾名思义,是运行在用户空间的线程。它是通过 线程库(如 pthread、Java 的线程类等)在用户程序中创建和管理的。

特点:

  • 不需要操作系统内核支持,全部在线程库中搞定。
  • 切换速度快:线程之间切换不需要陷入内核(省去了用户态和内核态的切换)。
  • 缺点是:一荣俱荣一损俱损。如果一个线程被阻塞(比如 I/O),整个进程都会挂起。

想象你和朋友一起排队打游戏(排队系统是用户线程库),你排到一半突然去上厕所(阻塞),那后面的人也只能等你回来——因为只有一个游戏机位(进程只在一个 CPU 上运行)。


内核线程(Kernel Thread)是啥?

内核线程是真正由 操作系统内核管理的线程,系统可以感知到它们的存在。线程的调度、切换由操作系统来控制。

特点:

  • 线程调度由内核完成,调度精细且高效。
  • 可以在多核处理器上实现真正的并行
  • 某个线程被阻塞,不影响同进程的其他线程。

继续刚才的比喻:

  • 内核线程就像是一个游戏厅(多核 CPU)里的多个游戏机(内核线程),你和朋友可以分开玩。你去上厕所,朋友还可以继续玩。

用户线程和内核线程的区别

项目用户线程(User Thread)内核线程(Kernel Thread)
是否内核可见
创建与销毁用户级线程库控制操作系统控制
切换代价小,无需内核态切换大,涉及内核态切换
系统调用影响可能阻塞整个进程只阻塞当前线程
多处理器支持不好,不能并行运行支持真正并行

两者优缺点总结

用户线程的优点:

  1. 开销小:创建、销毁快,切换快。
  2. 灵活:可以自定义调度策略。
  3. 可以在不支持多线程的系统上实现

用户线程的缺点:

  1. 一个线程阻塞,全体挂起。
  2. 无法利用多核 CPU 实现并行。

内核线程的优点:

  1. 真正并发:支持多核并行。
  2. 阻塞隔离:一个线程阻塞不影响其他线程。

内核线程的缺点:

  1. 开销大:线程调度需要系统干预。
  2. 创建销毁慢,上下文切换成本高。

什么是僵尸进程、孤儿进程、守护进程?

僵尸进程(Zombie Process)

子进程退出,但父进程没调用 wait() 回收它的状态信息,子进程就变成了僵尸。

它已经“死了”,但进程表里还留着尸体(资源信息没释放,PID 被占用)。

危害:

  • 僵尸进程多了,PID 会耗尽,系统无法创建新进程!

如何避免僵尸进程?

  • 父进程要记得调用 wait()waitpid()
  • 如果父进程没写好,可以杀掉父进程,让僵尸进程变成孤儿进程被 init(PID=1)接管并回收。

孤儿进程(Orphan Process)

子进程还活着,但父进程已经挂了。

此时,操作系统会让 init(进程号 1)来接管这些孤儿,并负责善后。


守护进程(Daemon)

守护进程是 一直在后台默默运行 的进程,比如 crond 定时任务、nginxmysqld 等等。

它通常在启动时就脱离了终端、脱离父进程,由 init 进程接管。

特点:

  • 在系统后台运行
  • 不和终端绑定
  • 通常被设置为系统服务

僵尸进程、孤儿进程、守护进程的对比

类型状态被谁管理是否会影响系统资源
僵尸进程已退出但未回收父进程未处理会占用 PID,长期不回收会出问题
孤儿进程父进程先退出init 进程接管会被自动回收
守护进程主动脱离父进程init 进程接管通常作为后台服务

相关文章:

  • 抗干扰CAN总线通信技术在分布式电力系统中的应用
  • 科技自立+产业周期:透视人工智能的配置机遇
  • RTP Payload Format for H.264 Vide(1)
  • Java Lambda 表达式详解:发展史、语法、使用场景及代码示例
  • Vue3性能优化全攻略:从原理到极致性能实战
  • vue入门:指令
  • 蓝桥杯 2025 C++组 省 B 题解
  • 面试算法高频05-bfs-dfs
  • 科技赋能记忆共生-郑州
  • 【Java学习笔记】Java第一课,梦开始的地方!!!
  • (八)lerobot开源项目扩展so100的仿真操控(操作记录)
  • 【NIO番外篇】之组件 Channel
  • 《车辆人机工程-》实验报告
  • Linux进程替换与自定义shell详解
  • redisson的unlock方法
  • 行星际激波在日球层中的传播:Propagation of Interplanetary Shocks in the Heliosphere (第一部分)
  • GO语言入门:字符串处理1(打印与格式化输出)
  • Embedding质量评估、空间塌缩、 Alignment Uniformity
  • 【数据结构_5】链表(模拟实现以及leetcode上链表相关的题目)
  • 【AI】SpringAI 第一弹:SpringAI 的兴起介绍
  • 福州交警:一小型汽车因操作不当撞上汽车和电动车,致2人死亡
  • 商务部新闻发言人就中美经贸对话磋商情况答记者问
  • 美“群聊泄密门”始作俑者沃尔兹将离职
  • 保险经纪公司元保在纳斯达克挂牌上市,去年净赚4.36亿元
  • 马上评|扩大高速免费救援范围,打消出行后顾之忧
  • 山西太原小区爆炸事故已造成17人受伤