一、趣味开场:为什么会有线程?

很多人学操作系统,进程和线程总是傻傻分不清楚。我们先讲个生活化的例子:你开了一家面包加工厂,要完成揉面、烘烤、包装三道工序。

  • 如果全厂只有一个工人从头干到尾,效率极低 —— 这就是单进程单线程
  • 如果你再开一家一模一样的工厂,招新工人买新设备,成本极高 —— 这就是多进程并发
  • 最划算的方式:还是这一家工厂,多招几个工人,共用厂房、烤箱、面粉,分工同时干活 —— 这就是多线程

线程的本质,就是进程里 “真正干活的工人”。


二、核心比喻:进程 = 工厂,线程 = 工人

我们用一套完整的工厂模型,把所有概念对应清楚,一眼就能看懂两者的本质差异:

表格

操作系统概念 工厂比喻 说明
进程 独立的面包工厂 拥有独立的厂房、仓库、设备,和其他工厂完全隔离
线程 工厂里的工人 共享工厂的所有公共资源,自己只保留工位和随身工具
进程地址空间 工厂的场地与仓库 每个进程独有,A 工厂的面粉不会跑到 B 工厂
线程栈 / 寄存器 工人的操作台、手套 每个线程私有,互不干扰
全局变量 / 堆内存 公共面粉、烤箱 所有线程共享,也是矛盾的发源地
进程切换 搬去另一个工厂干活 成本极高,要换全套资源
线程切换 换一个工人上岗 成本极低,只需要交接工位

进程与线程结构示意图

一句话总结:进程是资源分配的最小单位,线程是 CPU 调度的最小单位。进程只管囤资源,真正跑任务的全是线程。


三、多线程到底好在哪?

用工厂的逻辑一想就明白:

  1. 并发效率高:多个工人同时干活,揉面的不耽误包装的,任务并行推进。
  2. 切换成本低:同一个工厂里换工人,不用重新租厂房买设备,只需要交接工位,开销只有进程切换的几十分之一。
  3. 通信成本低:工人之间喊一声就能传消息,直接共用仓库里的材料,不用跨工厂寄快递。
  4. 资源利用率高:烤箱闲着的时候,别的工人可以用,不会让设备空转。

四、动手写第一个多线程程序

我们用 C 语言标准的pthread库,模拟两个工人同时干活的场景,直观感受多线程的并发效果。

c

运行

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

// 线程1:揉面工人的任务
void *worker_knead(void *arg) {
    for (int i = 1; i <= 3; i++) {
        printf("揉面工人:正在揉第%d个面团\n", i);
        sleep(1); // 模拟干活耗时
    }
    return NULL;
}

// 线程2:包装工人的任务
void *worker_pack(void *arg) {
    for (int i = 1; i <= 3; i++) {
        printf("包装工人:正在包装第%d个面包\n", i);
        sleep(1);
    }
    return NULL;
}

int main() {
    pthread_t t1, t2;

    // 创建两个线程,相当于招两个工人同时开工
    pthread_create(&t1, NULL, worker_knead, NULL);
    pthread_create(&t2, NULL, worker_pack, NULL);

    // 等待两个工人都干完活再下班
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    printf("今日生产任务全部完成\n");
    return 0;
}

编译命令:gcc demo.c -o demo -lpthread

运行后会看到两个工人的输出交替出现,就像两个人真的在同时干活一样。

五、线程基础认知思维导图

六、小结

线程从来不是什么高深的黑科技,它就是操作系统为了 “让一个程序同时干多件事” 设计出来的轻量级执行单元。记住 “进程管资源,线程干活” 这个核心,你就跨过了多线程的第一道门槛。

但工人多了就会抢资源、闹矛盾,线程世界也是一样。下一篇我们就来讲讲多线程最核心的难题:线程之间怎么安全协作。

谢谢

Logo

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

更多推荐