跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++

C++ 视角下的进程、线程与协程:概念、原理及应用场景

C++ 视角下对比进程、线程与协程的核心差异。进程拥有独立内存空间,隔离性好但创建切换开销大;线程共享进程内存,通信方便但存在线程安全问题;协程为轻量级用户态调度,适合高并发 I/O 密集型任务。文章通过代码示例展示了 fork+exec、std::thread 及 C++20 coroutine 的实现细节,并总结了三者适用场景。

SecGuard发布于 2026/3/15更新于 2026/9/666 浏览

1. 进程(Process)

概念(C++ 视角)

  • 进程是程序的一次运行实例,拥有独立的内存空间(代码段、数据段、堆、栈)。
  • C++ 程序运行后,OS 会为它创建一个进程。
  • 不同进程之间内存隔离,需要 IPC(管道、共享内存、Socket 等)通信。

优点

优点说明
隔离性好、稳定性高一个进程崩溃不会影响其他进程
安全性好内存独立,不易被非法访问
适合多核并行多进程可充分利用 CPU 核心

缺点

缺点说明
创建开销大需要分配独立内存空间
切换开销大进程切换需要保存大量上下文
通信复杂IPC 通信比线程复杂得多

应用场景

  • Chrome 浏览器多进程架构(保证一个 Tab 崩溃不影响其它)
  • 后端服务拆成多个微服务(隔离性高)
  • 高安全、高可靠场景(银行、支付模块)

1. 进程示例(fork + exec,Linux)

Windows 不能用 fork(),Linux/Unix 可以。示例中父进程创建子进程,子进程执行 ls 命令。

#include <iostream>
#include <unistd.h>
#include <sys/wait.h>

int main() {
    pid_t pid = fork();
    if (pid < 0) {
        std::cerr << "Fork failed\n";
        return 1;
    }
    if (pid == 0) {
        // 子进程
        std::cout << "Child process PID: " << getpid() << "\n";
        execlp("ls", "ls", "-l", NULL); // 执行 ls -l
    } else {
        // 父进程
        std::cout << "Parent process PID: " << getpid() << "\n";
        wait(NULL); // 等待子进程结束
        std::cout << "Child process finished.\n";
    }
    return 0;
}
  • 展示了:
    • 父进程/子进程地址空间独立
    • fork + exec
    • 进程阻塞等待子进程完成

2. 线程(Thread)

概念(C++ 视角)

  • 线程是进程中的最小执行单位。
  • C++ 中可用 std::thread 创建。
  • 同一进程内的线程共享内存(代码段、堆),但有自己的栈。

优点

优点说明
创建开销比进程小无需独立内存空间
切换比进程快共享大部分资源
通信方便直接共享内存即可

缺点

缺点说明
线程安全问题严重多线程共享内存 → 有竞争风险
容易死锁mutex、condition_variable 等用不好就会死锁
一个线程崩溃会导致整个进程崩溃共享内存导致稳定性较差

应用场景

  • 计算密集型任务:并行排序、矩阵运算(利用多核 CPU)
  • I/O 密集型任务:服务器线程池
  • 后台任务:日志线程、定时任务线程

2. 线程示例(std::thread)

用 C++ 标准库创建一个线程并等待其执行。

#include <iostream>
#include <thread>

void worker(int id) {
    std::cout << "Thread " << id << " is running.\n";
}

int main() {
    std::thread t(worker, 1); // 创建线程
    if (t.joinable()) {
        t.join(); // 等待线程结束
    }
    std::cout << "Thread finished.\n";
    return 0;
}
  • 展示了:
    • 如何创建线程
    • 如何 join
    • 线程共享进程数据

3. 协程(Coroutine)

概念(C++ 视角)

  • C++20 正式原生支持协程(co_await, co_yield, co_return)。
  • 用户态调度:协程的切换在用户空间进行,不需要操作系统。
  • 轻量级执行单元,数量可以达到几十万甚至百万级别。

原理简述

  • 协程不会主动抢占 CPU,需要手动 co_await 等方式让出执行权。
  • 和线程不同:协程不是系统级调度,而是语言/库层调度。

优点

优点说明
极轻量级创建成本比线程小几个数量级
切换开销非常低不涉及 OS 调度
适合大量并发任务比如 10 万个 socket 连接
编程模型简单写法像同步代码但本质异步

缺点

缺点说明
不是并行,只是并发单线程协程不能利用多核 CPU
需要协程调度器C++20 提供语言原语但无完整调度库
协程逻辑复杂时语义可能难理解

应用场景

  • 超高并发网络服务器(如用协程替代回调)
  • 游戏引擎脚本系统(逻辑暂停/恢复很适合协程)
  • GUI 程序的异步任务
  • 异步 I/O(文件读写、socket 等)

3. 协程示例(C++20 coroutine)

使用 std::coroutine_handle + promise 自定义一个简单协程。实现一个'打印任务'协程,可暂停/恢复。

#include <iostream>
#include <coroutine>

// 协程返回对象
struct Task {
    struct promise_type {
        Task get_return_object() {
            return Task{ std::coroutine_handle<promise_type>::from_promise(*this) };
        }
        std::suspend_never initial_suspend() { return {}; }
        std::suspend_always final_suspend() noexcept { return {}; }
        void return_void() {}
        void unhandled_exception() { std::exit(1); }
    };
    std::coroutine_handle<promise_type> handle;
    Task(std::coroutine_handle<promise_type> h) : handle(h) {}
    ~Task() { if (handle) handle.destroy(); }
};

// 一个可挂起协程
Task myCoroutine() {
    std::cout << "Coroutine step 1\n";
    co_await std::suspend_always{}; // 暂停
    std::cout << "Coroutine step 2\n";
    co_await std::suspend_always{}; // 再暂停
    std::cout << "Coroutine finished\n";
}

int main() {
    auto task = myCoroutine(); // 创建协程(不会立即结束)
    std::cout << "Resume coroutine...\n";
    task.handle.resume();
    std::cout << "Resume again...\n";
    task.handle.resume();
    std::cout << "Resume last time...\n";
    task.handle.resume();
    return 0;
}

运行输出类似:

Coroutine step 1
Resume coroutine...
Coroutine step 2
Resume again...
Coroutine finished
Resume last time...
  • 展示了:
    • 协程的挂起/恢复机制
    • 完全用户态,不需要线程/进程调度
    • C++20 协程语法:co_await、co_return

4. 三者的直观对比

对比项进程线程协程
内存空间独立共享共享(在同线程内)
创建开销大中极小
切换成本最大中极小(用户态)
是否并行是是否(除非多个线程跑协程)
是否安全最安全最不安全与线程一致
稳定性高中中
数量级少(几十)中(几千)多(10 万+)
使用难度中高中

总结

  • 进程:最安全,但最重,适合隔离性强的任务
  • 线程:共享内存并行执行,适合 CPU 密集任务
  • 协程:超轻量级并发,适合 I/O 密集型和高并发服务器

目录

  1. 1. 进程(Process)
  2. 概念(C++ 视角)
  3. 优点
  4. 缺点
  5. 应用场景
  6. 1. 进程示例(fork + exec,Linux)
  7. 2. 线程(Thread)
  8. 概念(C++ 视角)
  9. 优点
  10. 缺点
  11. 应用场景
  12. 2. 线程示例(std::thread)
  13. 3. 协程(Coroutine)
  14. 概念(C++ 视角)
  15. 原理简述
  16. 优点
  17. 缺点
  18. 应用场景
  19. 3. 协程示例(C++20 coroutine)
  20. 4. 三者的直观对比
  21. 总结

更多推荐文章

查看全部
  • 基于 Vue 和 Java 的篮球馆场地预约系统设计
  • Microi 吾码:服务器虚拟化资源管理与网络配置实践
  • Spring Data JPA 中 EntityManager 核心用法与持久化操作指南
  • 基于 Spring Boot 的流浪动物救助与管理系统的设计与实现
  • 医疗 AI 场景下的模型融合与集成策略
  • C++ 继承:面向对象代码复用的核心机制
  • Buzz 离线语音转文字工具:Whisper 模型集成与使用指南
  • Java 高频面试题汇总与核心解析
  • OpenCode 开源 AI 编程助手简介
  • 利用 Python 进行数据分析:核心流程与库详解
  • Gemini 全能 QQ 机器人部署手册 (V1.0 Release)
  • 员工管理系统设计与实现
  • 基于 Rokid AR 眼镜的会议议程管理助手开发
  • Kubernetes AI 推理服务部署与优化实战
  • Python 实现 UDP 传输 Opus 音频
  • ChatWiki 微信生态企业 AI 知识库,支持多模型与零代码 Agent 搭建
  • Gitea 本地部署指南:安装配置与常用 Git 命令实战
  • 大模型四大技术架构解析:Prompt、Agent、RAG 与微调
  • ChatGPT 保护指令:提升 GPTs 提示词与知识库文件安全性
  • 前端权限控制架构设计:告别硬编码判断

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online