共享内存线程模型与线程库

共享内存线程模型与线程库

2025 南京大学《操作系统原理》
共享内存线程模型与线程库

并发编程:动机

void http_server(int fd) {
    while (1) {
        nread = read(fd, buf, 1024);
        handle_request(buf, nread);
    }
}

如果 buf 到来的时间不确定?

  • 瞬间有大量请求到来
    • 代码等 handle_request 完成才读取下一个请求
    • 如果系统里有多个 CPU,这就更浪费了
  • 我们想要有共享内存的进程
2025 南京大学《操作系统原理》
共享内存线程模型与线程库

解决方法:加一个操作系统 API

C 程序的状态机模型

  • 初始状态:main(argc, argv, envp)
  • 状态迁移:执行一条语句 (指令)

多线程程序的状态机模型

  • 增加一个特殊的系统调用:spawn()
    • 增加一个 “状态机”,有独立的栈,但共享全局变量
  • 状态迁移:选择一个状态机执行一条语句 (指令)
    • Let's do it with model checker
2025 南京大学《操作系统原理》
共享内存线程模型与线程库

并发 v.s. 并行

并发

  • 逻辑上的 “同时执行”
    • 可以由操作系统/运行库模拟出的 “轮流执行”
    • (也可以是真正同时执行)

并行

  • 真正意义上的 “同时执行”
  • 有 (共享内存的) 多个处理器
    • 同时执行指令 (load/store 访问共享内存)
2025 南京大学《操作系统原理》
共享内存线程模型与线程库

多处理器编程:入门

简化的线程 API (thread.h)

  • spawn(fn)
    • 创建一个入口函数是 fn 的线程,并立即开始执行
      • void fn(int tid) { ... }
      • 参数 tid 从 1 开始编号
  • join()
    • 等待所有运行线程的返回
      • main 返回默认会 join 所有线程
    • 行为:while (num_done != num_threads) ;
2025 南京大学《操作系统原理》
共享内存线程模型与线程库

多处理器编程入门,就这么简单

#include <thread.h>

int x = 0, y = 0;

void inc_x() { while (1) { x++; sleep(1); } }
void inc_y() { while (1) { y++; sleep(2); } }

int main() {
    spawn(inc_x);
    spawn(inc_y);
    while (1) {
        printf("\033[2J\033[H");
        printf("x = %d, y = %d", x, y);
        fflush(stdout);
    }
}
  • 这个程序 “证明” 了全局变量确实是共享的
2025 南京大学《操作系统原理》
共享内存线程模型与线程库

更多的问题

多线程程序真的利用了多处理器吗?

  • 并发确定了,那是不是真并行?

线程是否具有独立堆栈?

  • 如果是,栈的范围?

如何用 gdb 单步调试多线程程序?

  • LLM 帮你读过 The Friendly Manual
  • EuroSys 时的对话:System 人最擅长的就是底层工具的使用,曾经是 “做 system” 的壁垒;但现在有 LLM 了,这都不算什么了
2025 南京大学《操作系统原理》