进程通信与线程通信:全面总结 + 使用场景 + 优缺点 + 使用方法

文章目录

  • 进程与线程的通信方式全面总结
  • [第一部分:线程通信(Thread Communication)](#第一部分:线程通信(Thread Communication))
    • [1. 全局变量共享(最简单方式)](#1. 全局变量共享(最简单方式))
      • [✔ 使用场景](#✔ 使用场景)
      • [✔ 优点](#✔ 优点)
      • [✔ 缺点](#✔ 缺点)
      • [✔ 使用方法](#✔ 使用方法)
    • [2. 互斥锁(Mutex):解决互斥问题](#2. 互斥锁(Mutex):解决互斥问题)
      • [✔ 使用场景](#✔ 使用场景)
      • [✔ 优点](#✔ 优点)
      • [✔ 缺点](#✔ 缺点)
      • [✔ 使用方法](#✔ 使用方法)
    • [3. 信号量(Semaphore):互斥 + 同步二合一](#3. 信号量(Semaphore):互斥 + 同步二合一)
      • [✔ 使用场景](#✔ 使用场景)
      • [✔ 优点](#✔ 优点)
      • [✔ 缺点](#✔ 缺点)
      • [✔ 使用方法](#✔ 使用方法)
    • [4. 条件变量(Condition Variable)](#4. 条件变量(Condition Variable))
      • [✔ 使用场景](#✔ 使用场景)
      • [✔ 优点](#✔ 优点)
      • [✔ 缺点](#✔ 缺点)
      • [✔ 使用方法](#✔ 使用方法)
    • [5. 读写锁(RWLock)](#5. 读写锁(RWLock))
      • [✔ 使用场景](#✔ 使用场景)
      • [✔ 优点](#✔ 优点)
      • [✔ 缺点](#✔ 缺点)
      • [✔ 使用方法](#✔ 使用方法)
    • [6. 屏障(Barrier)](#6. 屏障(Barrier))
      • [✔ 使用场景](#✔ 使用场景)
      • [✔ 优点](#✔ 优点)
      • [✔ 缺点](#✔ 缺点)
      • [✔ 使用方法](#✔ 使用方法)
  • 第二部分:进程通信(IPC)
    • [1. 匿名管道(pipe)](#1. 匿名管道(pipe))
      • [✔ 使用场景](#✔ 使用场景)
      • [✔ 优点](#✔ 优点)
      • [✔ 缺点](#✔ 缺点)
      • [✔ 使用方法](#✔ 使用方法)
    • [2. 命名管道(FIFO)](#2. 命名管道(FIFO))
      • [✔ 使用场景](#✔ 使用场景)
      • [✔ 优点](#✔ 优点)
      • [✔ 缺点](#✔ 缺点)
      • [✔ 使用方法](#✔ 使用方法)
    • [3. 消息队列(Message Queue)](#3. 消息队列(Message Queue))
      • [✔ 使用场景](#✔ 使用场景)
      • [✔ 优点](#✔ 优点)
      • [✔ 缺点](#✔ 缺点)
    • [4. 共享内存(Shared Memory):最快 IPC](#4. 共享内存(Shared Memory):最快 IPC)
      • [✔ 使用场景](#✔ 使用场景)
      • [✔ 优点](#✔ 优点)
      • [✔ 缺点](#✔ 缺点)
      • [✔ 使用方法](#✔ 使用方法)
    • [5. 信号量(semget / semop)](#5. 信号量(semget / semop))
      • [✔ 使用场景](#✔ 使用场景)
      • [✔ 优点](#✔ 优点)
      • [✔ 缺点](#✔ 缺点)
    • [6. 信号(signal)](#6. 信号(signal))
      • [✔ 使用场景](#✔ 使用场景)
      • [✔ 优点](#✔ 优点)
      • [✔ 缺点](#✔ 缺点)
    • [7. 套接字(socket)](#7. 套接字(socket))
      • [① UNIX 域套接字 ------ 本地进程通信最快方式](#① UNIX 域套接字 —— 本地进程通信最快方式)
      • [✔ 使用场景](#✔ 使用场景)
      • [✔ 优点](#✔ 优点)
      • [✔ 使用方法](#✔ 使用方法)
      • [② TCP/IP 套接字 ------ 支持跨机器通信](#② TCP/IP 套接字 —— 支持跨机器通信)
      • [✔ 使用场景](#✔ 使用场景)
      • [✔ 优点](#✔ 优点)
      • [✔ 缺点](#✔ 缺点)
    • [8. mmap 文件映射](#8. mmap 文件映射)
      • [✔ 使用场景](#✔ 使用场景)
      • [✔ 优点](#✔ 优点)
      • [✔ 缺点](#✔ 缺点)
  • 第三部分:两者对比总结(非常重要)
  • 最终总结(选择建议)
    • [✔ 如果是线程之间通信:](#✔ 如果是线程之间通信:)
    • [✔ 如果是进程之间通信:](#✔ 如果是进程之间通信:)

进程与线程的通信方式全面总结

(使用场景 + 优缺点 + 使用方式)

在 Linux 系统中,程序的并发执行通常依赖 进程(Process)线程(Thread)

它们在运行时需要共享数据、协作执行,这就产生了:

  • 进程间通信(IPC)
  • 线程间通信(同步与共享数据)

本篇文章通过系统化的方式,为你总结所有通信方式、各自适用的场景、优缺点,并给出示例代码,帮助你快速掌握 Linux 下的并发编程。


第一部分:线程通信(Thread Communication)

线程共享同一进程空间,它们本身没有"通信",而是共享变量 + 使用同步原语控制访问顺序。

线程通信的核心是:

✔ 共享内存

✔ 同步机制保证线程安全

常用方式如下:


1. 全局变量共享(最简单方式)

✔ 使用场景

  • 多个线程共享某个变量(计数器、状态标志等)

✔ 优点

  • 简单、自然、不需要系统调用
  • 速度最快(线程共享内存)

✔ 缺点

  • 必须使用锁保护
  • 容易产生数据竞争(race condition)

✔ 使用方法

c 复制代码
int shared_value = 0;

void* worker(void* arg) {
    shared_value++;
    return NULL;
}

2. 互斥锁(Mutex):解决互斥问题

✔ 使用场景

  • 多线程访问共享资源时要保护临界区
  • 解决:同时只有一个线程能执行关键代码

✔ 优点

  • 机制简单
  • 用途广泛、稳定可靠

✔ 缺点

  • 使用不当容易造成死锁
  • 不能解决同步(等待条件)问题

✔ 使用方法

c 复制代码
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

pthread_mutex_lock(&lock);
// 临界区
pthread_mutex_unlock(&lock);

3. 信号量(Semaphore):互斥 + 同步二合一

✔ 使用场景

  • 线程同步(例如生产者-消费者)
  • 控制可同时访问资源的线程数量(计数信号量)

✔ 优点

  • 能实现互斥,也能实现同步
  • 支持计数,比 mutex 更灵活

✔ 缺点

  • 比 mutex 更难理解
  • 使用不当可能导致死锁

✔ 使用方法

c 复制代码
sem_t sem;
sem_init(&sem, 0, 1);

sem_wait(&sem);   // P 操作
// 临界区
sem_post(&sem);   // V 操作

4. 条件变量(Condition Variable)

✔ 使用场景

  • 一个线程等待某个条件成立(如 shared_data > 0)
  • 广泛用于生产者-消费者模型

✔ 优点

  • 比忙等(while循环)高效
  • 能使线程睡眠直到被唤醒

✔ 缺点

  • 必须配合互斥锁使用
  • 逻辑比 mutex 略复杂

✔ 使用方法

c 复制代码
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

pthread_mutex_lock(&mutex);
while (shared_data == 0)
    pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);

5. 读写锁(RWLock)

✔ 使用场景

  • 多个线程需要同时读取共享数据(读多写少)

✔ 优点

  • 允许多个线程读,提高并发度
  • 写操作仍然保证互斥

✔ 缺点

  • 写锁容易饥饿
  • 使用复杂度比 mutex 高

✔ 使用方法

c 复制代码
pthread_rwlock_t rwlock;

pthread_rwlock_rdlock(&rwlock);
// 读操作
pthread_rwlock_unlock(&rwlock);

6. 屏障(Barrier)

✔ 使用场景

  • 一组线程需要在某个同步点汇合,然后一起继续执行

✔ 优点

  • 解决"一次性全体同步"问题
  • 在多阶段算法中常用(并行计算)

✔ 缺点

  • 不常用于业务逻辑
  • 使用起来稍复杂

✔ 使用方法

c 复制代码
pthread_barrier_t barrier;
pthread_barrier_init(&barrier, NULL, thread_num);

pthread_barrier_wait(&barrier);

第二部分:进程通信(IPC)

进程完全隔离,不共享内存,因此需要借助内核的 IPC 机制交换数据。

按难度从简单到复杂排列:


1. 匿名管道(pipe)

✔ 使用场景

  • 父子进程通信
  • shell 的 ls | grep 就是管道

✔ 优点

  • 简单易用
  • 单向数据流很适合流水线处理

✔ 缺点

  • 只能用于父子进程
  • 单向流动、不能同时双向发

✔ 使用方法

c 复制代码
int fd[2];
pipe(fd);
write(fd[1], "hello", 5);
read(fd[0], buf, 5);

2. 命名管道(FIFO)

✔ 使用场景

  • 任意两个进程通信
  • 简单客户端-服务端模型

✔ 优点

  • 支持无关进程通信
  • API 简单

✔ 缺点

  • 同样是单向
  • 不适合彩信大量数据

✔ 使用方法

c 复制代码
mkfifo("myfifo", 0666);
int fd = open("myfifo", O_WRONLY);
write(fd, "hi", 2);

3. 消息队列(Message Queue)

✔ 使用场景

  • 多个进程之间发送消息
  • 适合小型命令通信(非大量数据)

✔ 优点

  • 有消息边界,不会出现黏包问题
  • 内核管理消息队列,稳定可靠

✔ 缺点

  • 队列大小有限制
  • 不适合大量数据传输

4. 共享内存(Shared Memory):最快 IPC

✔ 使用场景

  • 大量数据交换(视频、音频、图片等)
  • 性能要求极高的应用

✔ 优点

  • 最快的 IPC(几乎零开销)
  • 数据直接在同一块内存中共享

✔ 缺点

  • 必须使用同步机制(如信号量)
  • 编程复杂度略高

✔ 使用方法

c 复制代码
int shmid = shmget(1234, 1024, 0666|IPC_CREAT);
char* mem = shmat(shmid, NULL, 0);
// 读写 mem 即可

5. 信号量(semget / semop)

✔ 使用场景

  • 进程间同步(配合共享内存)
  • 避免多个进程同时访问共享资源

✔ 优点

  • 操作非常高效
  • 跨进程同步能力强

✔ 缺点

  • 只能做同步,不传数据
  • 使用略复杂

6. 信号(signal)

✔ 使用场景

  • 进程间发送异步事件(比如 kill 通知)

✔ 优点

  • 实现简单
  • 适合发送控制指令(终止进程)

✔ 缺点

  • 只能传递简单事件
  • 不适合传输数据

7. 套接字(socket)

分两种:

① UNIX 域套接字 ------ 本地进程通信最快方式

✔ 使用场景

  • 本地客户端-服务端
  • Nginx、Docker、MySQL 常用

✔ 优点

  • 和 TCP 几乎一样,但更快
  • 使用文件路径作为地址

✔ 使用方法

c 复制代码
int sock = socket(AF_UNIX, SOCK_STREAM, 0);
bind(sock, ... "/tmp/test.sock");

② TCP/IP 套接字 ------ 支持跨机器通信

✔ 使用场景

  • 网络程序必须用它(Web 服务器、聊天程序)

✔ 优点

  • 可跨主机通信
  • API 通用、功能强大

✔ 缺点

  • 效率比 UDS 和共享内存低
  • 涉及网络协议栈处理

8. mmap 文件映射

✔ 使用场景

  • 文件共享数据
  • 多进程共享内存但使用文件作为底层媒介

✔ 优点

  • 实现共享内存的另一种方式
  • 适合大量数据

✔ 缺点

  • 需要文件系统支持
  • 不适合频繁的同步操作

第三部分:两者对比总结(非常重要)

通信类型 适用对象 速度 是否共享内存 工程常用性
线程通信 同一进程内线程 🚀 非常快 ✔ 是 极常用
进程通信 完全独立的进程 ⚡ 中等 ❌ 否 常用

最终总结(选择建议)

✔ 如果是线程之间通信:

优先选择:

复制代码
共享变量 → mutex → cond → sem → rwlock

✔ 如果是进程之间通信:

顺序建议如下:

复制代码
大量数据 → 共享内存(最快)
本地通信 → UNIX 域套接字
跨主机 → TCP/IP socket
简单消息 → 队列
通知事件 → signal
父子进程 → pipe
相关推荐
SPC的存折5 小时前
1、Redis数据库基础
linux·运维·服务器·数据库·redis·缓存
爱学习的小囧6 小时前
VMware ESXi 6.7U3v 新版特性、驱动集成教程和资源包、部署教程及高频问答详情
运维·服务器·虚拟化·esxi6.7·esxi蟹卡驱动
小疙瘩6 小时前
只是记录自己发布若依分离系统到linux过程中遇到的问题
linux·运维·服务器
dldw7777 小时前
IE无法正常登录windows2000server的FTP服务器
运维·服务器·网络
我是伪码农7 小时前
外卖餐具智能推荐
linux·服务器·前端
Tomhex8 小时前
C语言内存安全防护指南
c语言
汤愈韬8 小时前
下一代防火墙通用原理
运维·服务器·网络·security
皮皮林5518 小时前
强烈建议大家使用 Linux 做开发?
linux
IMPYLH8 小时前
Linux 的 od 命令
linux·运维·服务器·bash
And_Ii8 小时前
LCR 168. 丑数
c++