一、基础核心概念通用定义

1. 进程 Process

操作系统资源分配最小单位:独立内存空间、文件句柄、CPU 上下文、堆 / 栈,进程间天然隔离,互不干扰;创建销毁开销大,切换成本高。

2. 线程 Thread

进程内调度最小单位:共享所属进程的内存、全局变量、文件描述符;仅私有栈、寄存器;切换轻量、开销小;同一进程线程数据共享,存在竞态条件,需要同步锁。

3. 关键区分

  • 多线程:同一进程内并发,共享资源;

  • 多进程:多个独立进程,资源隔离,靠 IPC 通信。


二、Python 多线程 & 多进程 核心实现与原理

(一)Python 多线程:threading 模块

核心限制:GIL 全局解释器锁(Python 最关键特性)

CPython 解释器存在 GIL:同一时刻,一个进程内只有一条线程能执行 Python 字节码

  1. CPU 密集场景:多线程几乎无法多核并行,只能交替并发,速度不如单线程;

  2. IO 密集场景(网络、文件、sleep、数据库):线程阻塞时会释放 GIL,多线程可大幅提升效率。

1. 核心 API

import threading
import time

def task(name):
    print(f"线程{name}启动")
    time.sleep(1)  # IO阻塞,释放GIL
    print(f"线程{name}结束")

if __name__ == "__main__":
    t1 = threading.Thread(target=task, args=("A",))
    t2 = threading.Thread(target=task, args=("B",))
    t1.start()
    t2.start()
    t1.join()
    t2.join()

2. 同步工具(解决共享变量竞争)

threading.Lock / RLock / Semaphore / Condition / Event

3. 线程池:concurrent.futures.ThreadPoolExecutor

简化批量线程管理,自动复用线程,不用手动创建销毁。

Python 线程特点总结

  1. 共享进程堆、全局变量,通信简单(直接读写变量,配合锁);

  2. GIL 锁死多核 CPU 并行,不适合计算密集型任务

  3. 轻量、创建快,IO 场景首选;

  4. 异常、死锁问题和 C++ 线程同源。

(二)Python 多进程:multiprocessing 模块

核心原理:绕开 GIL

每个子进程拥有独立 Python 解释器 + 独立 GIL,天然支持多核 CPU 并行计算。 操作系统层面调用 fork() (Linux/macOS) / 创建全新进程 (Windows),每个进程拥有独立内存拷贝,进程间数据默认隔离。

1. 核心 API

from multiprocessing import Process

def task(name):
    print(f"进程{name}执行,PID:{os.getpid()}")

if __name__ == "__main__":
    p1 = Process(target=task, args=("P1",))
    p2 = Process(target=task, args=("P2",))
    p1.start()
    p2.start()
    p1.join()
    p2.join()

2. 进程间通信 IPC(无法直接共享变量)

  • Queue:安全消息队列;

  • Pipe:双端管道;

  • Manager:共享容器 (list/dict),底层走 IPC;

  • Value/Array:共享内存基础数值。

3. 进程池:ProcessPoolExecutor

批量调度多进程,适合大规模 CPU 计算。

Python 多进程特点

  1. 多核并行,完美适配数值计算、AI 训练、数据处理;

  2. 进程内存完全拷贝,创建 / 切换开销远大于线程;

  3. 进程隔离,一个进程崩溃不会带走主程序;

  4. Windows 必须写 if __name__ == "__main__" 防无限递归创建进程;

  5. IPC 通信有性能损耗,频繁数据交互不推荐。

Python 线程 / 进程选型总结

  • IO 密集(爬虫、文件读写、接口请求):threading 多线程

  • CPU 密集(矩阵运算、循环计算):multiprocessing 多进程


三、C++ 多线程 & 多进程 核心实现与原理

(一)C++ 多线程:C++11 标准库 <thread>

核心特点:无 GIL,原生操作系统线程封装

C++ 线程直接映射 OS 内核线程,无全局锁限制,同一进程多线程可充分利用多核 CPU 并行

1. 基础示例

cpp

运行

#include <thread>
#include <iostream>
#include <chrono>

void task(std::string name) {
    std::cout << "线程 " << name << " 运行\n";
    std::this_thread::sleep_for(std::chrono::seconds(1));
}

int main() {
    std::thread t1(task, "A");
    std::thread t2(task, "B");
    t1.join();
    t2.join();
    return 0;
}

2. 同步互斥工具

<mutex>std::mutexstd::recursive_mutexstd::lock_guardstd::unique_lock 条件变量:std::condition_variable 信号量 (C++20):std::semaphore 原子操作:std::atomic<T> 无锁并发。

3. 线程池

C++ 标准无内置线程池,需自行封装或使用第三方库(Boost、Abseil)。

C++ 线程核心特性

  1. 无 GIL,多核并行计算性能极强;

  2. 共享进程地址空间,全局变量、堆内存全部共享,极易数据竞争;

  3. 手动管理资源,忘记join()会触发程序崩溃(terminate);

  4. 内存模型:C++ 内存序 memory_order 精细控制 CPU 缓存可见性;

  5. 开销极低,调度完全由操作系统负责。

(二)C++ 多进程:无标准跨平台库,依赖系统 API

C++ 标准库没有封装进程,必须调用操作系统原生接口:

  • Linux/macOS:POSIX API fork()exec()

  • Windows:Win32 API CreateProcess

1. Linux fork 原理

fork() 调用后复制父进程完整内存(写时复制 COW),返回两次:

  • 父进程:返回子进程 PID;

  • 子进程:返回 0; 父子进程内存独立,仅文件描述符默认继承。

Linux 简单示例:

cpp

运行

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

int main() {
    pid_t pid = fork();
    if (pid == 0) {
        // 子进程
        std::cout << "子进程 PID:" << getpid() << "\n";
    } else if (pid > 0) {
        // 父进程,等待子进程结束
        wait(nullptr);
        std::cout << "父进程等待子进程完成\n";
    }
    return 0;
}

2. C++ 进程间通信 IPC(跨进程数据交换)

Linux:管道 pipe、命名管道 FIFO、共享内存 shmget、消息队列、Socket、信号 signal Windows:匿名管道、命名管道、内存映射文件

C++ 多进程特点

  1. 完全内存隔离,单个进程崩溃不影响其他进程;

  2. 创建销毁开销巨大,内存拷贝成本高;

  3. 无统一标准 API,Linux 与 Windows 代码完全不兼容;

  4. IPC 通信繁琐,需要手动管理句柄、同步;

  5. 多用于服务隔离、故障容灾场景。

C++ 线程 / 进程选型总结

  • CPU 密集计算、低延迟并发:std::thread 多线程(多核并行无锁限制)

  • 服务隔离、独立故障域、权限隔离:多进程 (fork/CreateProcess)


四、Python 与 C++ 并发核心差异总表

表格

维度 Python(threading/multiprocessing) C++(std::thread / OS 进程 API)
多线程多核并行 受 GIL 限制,CPU 密集无法多核并行 无全局锁,原生多核并行
线程资源开销 轻量,但 GIL 限制算力 极轻量,调度效率高
多进程实现 标准库 multiprocessing 跨平台封装 无标准库,依赖系统原生 API
进程内存模型 子进程完整拷贝,Manager 提供共享容器 fork 写时复制 / Windows 全新内存,手动共享内存
线程数据共享 直接共享全局变量,依赖 Lock 同步 共享整个进程地址空间,atomic/mutex 精细同步
IPC 难度 内置 Queue/Pipe,开箱即用 底层系统调用,代码量大、跨平台难
适用场景 IO 多线程;CPU 计算多进程 高性能计算多线程;服务隔离多进程
内存控制 GC 自动回收,不用手动管理 手动管理内存,野指针、内存泄漏风险高
跨平台一致性 threading/multiprocessing 一套代码跑 Win/Linux 线程跨平台;进程 Linux/Windows 代码分离

五、核心概念对比总结

1. 线程层面核心区别

  1. Python 致命限制 GIL:解释器层面强制单字节码执行,多线程仅 IO 并发,计算场景失效;

  2. C++ 原生内核线程:直接调度 CPU 核心,无任何全局锁,多线程并行算力拉满,是高性能并发基础; 两者共性:同进程线程共享内存,都需要互斥锁解决竞争,线程切换开销都远小于进程。

2. 进程层面核心区别

  1. Python:封装好multiprocessing,屏蔽操作系统差异,内置成熟 IPC 工具,上手简单;代价是每个进程独立解释器,内存占用高;

  2. C++:无标准进程封装,必须区分 Linux/Windows 系统调用,IPC 全部手动实现;优势是底层可控、无解释器额外内存开销,适合大型后台服务隔离。

3. 设计思路差异

  • Python 并发设计:优先牺牲计算性能,换取开发效率,靠多进程绕过 GIL 弥补多核短板;

  • C++ 并发设计:贴近操作系统底层,零额外抽象开销,追求极致性能,开发成本更高。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐