目录

一、进程(Process)

二、线程(Thread)

三、POSIX 线程(pthread)

四、线程同步机制

五、互斥锁的几种类型(按特性分)

六、C++ 标准库(推荐,跨平台)—— std::thread 及周边(C++11 / C++20 扩展)

七、面试常见问题


一、进程(Process)

1. 定义

进程是程序运行的实例
每启动一个可执行文件,操作系统就创建一个进程,分配独立的资源(内存、文件描述符、寄存器状态等)。

2. 特点

特征 说明
独立性 每个进程有独立的地址空间、堆、栈、全局变量
隔离性 一个进程崩溃通常不会影响其他进程
通信复杂 不同进程之间不能直接访问内存,需要 IPC(进程间通信)机制

3. 地址空间划分

进程的典型内存布局:

高地址
│
│ 栈(Stack)       ← 局部变量、函数调用
│ 堆(Heap)        ← 动态分配内存 malloc/new
│ 数据段(Data)    ← 全局变量、静态变量
│ 代码段(Code)    ← 程序指令
└────────────────
低地址
内存区域 内容 示例 是否线程共享
代码段 (Code) 程序指令(函数体) 函数定义、机器码 ✅ 共享
数据段 (Data) 全局变量、静态变量 int g; static int s; ✅ 共享
堆 (Heap) 动态分配内存 malloc()new ✅ 共享
栈 (Stack) 局部变量、函数调用栈 int local; ❌ 每个线程独立

二、线程(Thread)

1. 定义

线程是进程中的执行单元
同一进程内的多个线程共享进程资源(内存、文件句柄),但各自拥有独立的栈与寄存器。

⚙️ 线程是进程中的“执行单元”,是 CPU 调度的最小单位。

  • 一个进程可以有多个线程(共享同一块内存)。

  • 所有线程共享:

    • 全局变量 / 堆内存

    • 文件描述符 / I/O

  • 每个线程有自己的:

    • 栈空间

    • 程序计数器(执行位置)

2. 特点对比

项目 是否共享 说明
代码段 所有线程执行相同的程序指令
数据段 全局变量、静态变量共用
堆内存 一个线程分配的内存,别的线程也能访问
文件描述符 打开的文件或 socket 共用
每个线程有独立的函数调用栈
程序计数器(PC) 每个线程的执行位置独立

三、POSIX 线程(pthread

1. 创建线程

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

void* thread_func(void* arg) {
    printf("子线程执行: %s\n", (char*)arg);
    return NULL;
}

int main() {
    pthread_t tid;
    pthread_create(&tid, NULL, thread_func, "Hello Thread");
    pthread_join(tid, NULL);
    return 0;
}

2. 函数说明

函数 作用
pthread_create() 创建线程
pthread_exit() 退出当前线程
pthread_join() 等待线程结束(阻塞)
pthread_detach() 分离线程(不等待)
pthread_self() 获取当前线程ID

四、线程同步机制

线程共享内存,必须避免数据竞争(Data Race)

🧩 一、为什么需要线程同步?

在多线程程序中,多个线程共享同一片内存,比如全局变量、堆区数据等。
如果两个线程同时修改同一个变量,就会出现 数据竞争(Data Race)

📘 举个例子:

int counter = 0;

void* add_func(void* arg) {
    for (int i = 0; i < 100000; i++) {
        counter++;  // 多线程同时执行这里
    }
    return NULL;
}

int main() {
    pthread_t t1, t2;
    pthread_create(&t1, NULL, add_func, NULL);
    pthread_create(&t2, NULL, add_func, NULL);
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    printf("最终结果:%d\n", counter);
}

👉 你可能以为结果是 200000
但实际运行多次可能是 157634199876180231 …… 每次都不一样。

这是因为:

counter++ 不是一个原子操作,它其实包含了三步:

1. 读取 counter
2. 加 1
3. 写回 counter

两个线程交叉执行就会「互相覆盖」数据,导致结果错误。


🔒 1、互斥锁(Mutex)—— 保护“不能同时进的门”

互斥锁(Mutex,Mutual Exclusion)就像一个「锁着的门」:

  • 线程A 进入时要上锁;

  • 如果线程B 也想进,被挡在门外;

  • A 干完事后解锁;

  • B 才能进去。

pthread_mutex_t lock; // 声明一个互斥锁

void* add_func(void* arg) {
    for (int i = 0; i < 100000; i++) {
        pthread_mutex_lock(&lock);   // 上锁
        counter++;
        pthread_mutex_unlock(&lock); // 解锁
    }
    return NULL;
}

初始化与销毁

pthread_mutex_init(&lock, NULL);
...
pthread_mutex_destroy(&lock);

✅ 输出结果

多次运行结果都一样:

最终结果:200000

⚠️ 注意:

  • 上锁和解锁必须成对出现;

  • 如果一个线程上锁后忘了解锁,会导致其他线程永久等待(死锁)

  • 同一个线程可以多次上锁的情况称为“递归锁”(需要特别设置)。


🕹️ 2、条件变量(Condition Variable)—— 线程之间的“信号灯”

有时候我们需要让一个线程等另一个线程干完某件事再继续。
这时,用互斥锁不够,还需要“条件变量”来当信号灯。


📘 场景例子:

我们有两个线程:

  • waiter() —— 等待信号;

  • signaler() —— 发出信号。

pthread_mutex_t lock;
pthread_cond_t cond;
int ready = 0;  // 状态标志

void* waiter(void* arg) {
    pthread_mutex_lock(&lock);
    while (!ready) { // 条件不满足就等待
        pthread_cond_wait(&cond, &lock);
        // 等待时会自动解锁,等信号来了会重新加锁返回
    }
    printf("waiter 收到信号,继续执行!\n");
    pthread_mutex_unlock(&lock);
    return NULL;
}

void* signaler(void* arg) {
    sleep(1);  // 模拟准备过程
    pthread_mutex_lock(&lock);
    ready = 1;
    pthread_cond_signal(&cond); // 通知一个等待的线程
    pthread_mutex_unlock(&lock);
    return NULL;
}

main函数

int main() {
    pthread_t t1, t2;
    pthread_mutex_init(&lock, NULL);
    pthread_cond_init(&cond, NULL);

    pthread_create(&t1, NULL, waiter, NULL);
    pthread_create(&t2, NULL, signaler, NULL);

    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    pthread_mutex_destroy(&lock);
    pthread_cond_destroy(&cond);
}

💡 运行逻辑:

1️⃣ waiter 一开始发现 ready == 0,于是等待信号;
2️⃣ signaler 睡 1 秒后发信号;
3️⃣ waiter 被唤醒,输出:

waiter 收到信号,继续执行!

🧠 关键理解

pthread_cond_wait() 是「等待条件满足」的阻塞操作,
它必须和 pthread_mutex_t 一起使用,才能保证等待和修改状态是安全的。


⚖️ 3、信号量(Semaphore)—— 控制“能进多少人”

互斥锁相当于“一把锁”,一次只能进一个人。
信号量更灵活,可以同时允许多个线程访问资源。

比如一个“停车场”有 3 个车位,
信号量的初值设为 3,就表示最多同时 3 辆车能进去。


📘 示例:三个线程同时访问资源

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

sem_t sem;  // 声明信号量

void* task(void* arg) {
    int id = *(int*)arg;

    sem_wait(&sem); // 请求一个“许可”,车位 -1
    printf("线程 %d 进入临界区\n", id);
    sleep(2); // 模拟工作
    printf("线程 %d 离开临界区\n", id);
    sem_post(&sem); // 释放许可,车位 +1

    return NULL;
}

int main() {
    pthread_t t[5];
    int ids[5] = {1,2,3,4,5};

    sem_init(&sem, 0, 3); // 最多允许3个线程并发

    for (int i = 0; i < 5; i++)
        pthread_create(&t[i], NULL, task, &ids[i]);

    for (int i = 0; i < 5; i++)
        pthread_join(t[i], NULL);

    sem_destroy(&sem);
}

✅ 输出示例:

线程 1 进入临界区
线程 2 进入临界区
线程 3 进入临界区
(等待2秒)
线程 1 离开临界区
线程 4 进入临界区
线程 2 离开临界区
线程 5 进入临界区
...

🧠 你可以这样理解

信号量是「带计数的锁」:
sem_wait() 相当于抢车位;
sem_post() 相当于开走腾出车位。


🔁 三者对比总结

机制 控制粒度 是否阻塞 用途 典型场景
互斥锁 (Mutex) 一次一个 阻塞等待 防止数据竞争 多线程修改同一变量
条件变量 (Cond) 逻辑事件 阻塞等待 等待条件成立 生产者/消费者模型
信号量 (Sem) 可同时多个 阻塞等待 控制资源数量 限制并发访问数量
名称 作用 对应操作
Mutex 一次只让一个线程进入临界区 lock / unlock
Condition 线程等待特定事件 wait / signal
Semaphore 控制并发资源数量 wait / post

五、互斥锁的几种类型(按特性分)

在 Linux(pthread)里,互斥锁一共有 4 种类型:


🟩 1. 普通锁(NORMAL)

👉 特点:

  • 同一个线程不能重复加锁,否则会死锁(卡死)。

  • 简单、开销最小。

📘 适用场景:
一个函数里只加一次锁、解一次锁。

📗 示例:

pthread_mutex_t lock;

void* task(void* arg) {
    pthread_mutex_lock(&lock);
    printf("线程 %ld 进厨房炒菜\n", pthread_self());
    sleep(1);
    pthread_mutex_unlock(&lock);
    return NULL;
}

int main() {
    pthread_mutex_init(&lock, NULL);
    pthread_t t1, t2;
    pthread_create(&t1, NULL, task, NULL);
    pthread_create(&t2, NULL, task, NULL);
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    pthread_mutex_destroy(&lock);
}

🧩 运行效果:
两个线程轮流“炒菜”,不会同时操作厨房。


🟨 2. 检错锁(ERRORCHECK)

👉 特点:

  • 如果同一个线程重复加锁,会报错(返回 EDEADLK),而不是卡死。

  • 方便调试时发现错误。

📘 适用场景:
调试阶段,防止错误使用。

📗 示例:

pthread_mutex_t lock;
pthread_mutexattr_t attr;

pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
pthread_mutex_init(&lock, &attr);

pthread_mutex_lock(&lock);
printf("第一次加锁成功\n");

int ret = pthread_mutex_lock(&lock);
if (ret == EDEADLK)
    printf("错误:同一个线程重复加锁\n");

pthread_mutex_unlock(&lock);
pthread_mutex_destroy(&lock);

🧩 输出:

第一次加锁成功
错误:同一个线程重复加锁

🟦 3. 递归锁(RECURSIVE)

👉 特点:

  • 同一个线程可以重复加锁多次(比如函数递归调用时)。

  • 需要加锁几次 → 解锁同样次数才能真正释放。

📘 适用场景:
函数 A 调用函数 B,而 A 和 B 都用同一把锁。

📗 示例:

pthread_mutex_t lock;
pthread_mutexattr_t attr;

pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&lock, &attr);

void nested() {
    pthread_mutex_lock(&lock);
    printf("nested() 也进来了\n");
    pthread_mutex_unlock(&lock);
}

void work() {
    pthread_mutex_lock(&lock);
    printf("work() 加锁成功\n");
    nested();
    pthread_mutex_unlock(&lock);
}

int main() {
    work();
    pthread_mutex_destroy(&lock);
}

🧩 输出:

work() 加锁成功
nested() 也进来了

普通锁在这里会死锁,因为同一个线程重复加锁;
递归锁不会,因为它“记得是自己上的锁”。


🟥 4. 默认锁(DEFAULT)

👉 特点:

  • 等价于普通锁(NORMAL)。

  • pthread_mutex_init() 时默认的锁类型。

📗 示例:

pthread_mutex_t lock;
pthread_mutex_init(&lock, NULL);  // 默认锁

🧩 四、总结对比表(通俗版)

类型 是否可重入 是否检查重复加锁 适合场景 是否易死锁
NORMAL ❌ 否 ❌ 否 简单保护区 ✅ 容易死锁
ERRORCHECK ❌ 否 ✅ 是 调试、测试 ❌ 不会死锁
RECURSIVE ✅ 是 ✅ 是 递归调用 ❌ 不会死锁
DEFAULT ❌ 否 ❌ 否 默认使用 ✅ 容易死锁

六、C++ 标准库(推荐,跨平台)—— std::thread 及周边(C++11 / C++20 扩展)

适用场景:大多数应用、跨平台代码库、现代 C++ 项目(Linux/Windows/macOS/嵌入式 Linux)

主要接口(C++11 起)

  • std::thread(线程)

  • std::mutex, std::recursive_mutex, std::timed_mutex

  • std::lock_guard, std::unique_lock, std::scoped_lock

  • std::condition_variable, std::condition_variable_any

  • std::future, std::promise, std::packaged_task, std::async

  • std::atomic<T>(原子类型)

  • std::call_once, std::once_flag

  • thread_local(线程局部存储)

C++17 / C++20 补充

  • std::shared_mutex / std::shared_lock(读写锁)

  • std::latch, std::barrier(C++20 同步栅栏)

  • std::jthread(C++20,自动 join 并支持 stop token)

  • <semaphore>std::counting_semaphore(C++20)

  • std::stop_token(协作取消)


示例合集(跨平台、标准库)

1) 基本线程:std::thread

#include <thread>
#include <iostream>

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

int main() {
    std::thread t1(worker, 1);
    std::thread t2(worker, 2);
    t1.join();
    t2.join();
}

2) 互斥:std::mutex + lock_guard

#include <mutex>
#include <thread>

std::mutex m;
int counter = 0;

void inc() {
    for (int i=0;i<10000;i++){
        std::lock_guard<std::mutex> lk(m);
        ++counter;
    }
}

3) 条件变量(producer-consumer)

#include <condition_variable>
#include <mutex>
#include <queue>

std::queue<int> q;
std::mutex m;
std::condition_variable cv;
bool done = false;

void producer() {
    for (int i=0;i<10;i++) {
        {
            std::lock_guard<std::mutex> lk(m);
            q.push(i);
        }
        cv.notify_one();
    }
    {
        std::lock_guard<std::mutex> lk(m);
        done = true;
    }
    cv.notify_one();
}

void consumer() {
    while (true) {
        std::unique_lock<std::mutex> lk(m);
        cv.wait(lk, []{ return !q.empty() || done; });
        while (!q.empty()) {
            int v = q.front(); q.pop();
            // process v
        }
        if (done) break;
    }
}

4) Future / Promise / async

#include <future>
#include <iostream>

int compute(int x){ return x*2; }

int main(){
    std::future<int> fut = std::async(std::launch::async, compute, 21);
    int r = fut.get();
    std::cout << r << "\n"; // 42
}

5) 原子(高效计数器)

#include <atomic>
std::atomic<int> cnt{0};
void add(){ for(int i=0;i<10000;i++) cnt.fetch_add(1, std::memory_order_relaxed); }

6) 读写锁(shared_mutex)

#include <shared_mutex>

std::shared_mutex rw;
int shared_data = 0;

void reader() {
    std::shared_lock<std::shared_mutex> lk(rw);
    int v = shared_data; // 多个 reader 并行
}

void writer() {
    std::unique_lock<std::shared_mutex> lk(rw);
    shared_data++;
}

7) C++20:std::jthread 与 stop_token(优雅取消)

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

void worker(std::stop_token st) {
    while (!st.stop_requested()) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
    std::cout<<"stopped\n";
}

int main(){
    std::jthread t(worker);
    std::this_thread::sleep_for(std::chrono::seconds(1));
    t.request_stop(); // 发出取消请求
}

8) 信号量(C++20)

#include <semaphore>
std::counting_semaphore<10> sem(3); // 初始3

void task(){
    sem.acquire();
    // 临界区
    sem.release();
}

七、面试常见问题

1 础概念类

  1. 什么是进程(Process)?什么是线程(Thread)?两者有什么区别?

    • 进程:程序运行的实例,拥有独立的地址空间、资源(内存、文件句柄等)。 (GeeksforGeeks)

    • 线程:进程内的执行单元(最小调度单位),同一进程的线程共享地址空间、资源。

    • 区别:线程创建/切换比进程更轻;线程共享内存,进程一般隔离。 (ByteByteGo)

    • 面试回答可以提及:内存共享差别、上下文切换开销、资源隔离、通信方式等。

  2. 为什么同一个进程中可以有多个线程?有什么好处?

    • 多线程可以并发执行多个任务(尤其在多核或异步 I/O 场景)。

    • 共享资源(如堆、全局变量、文件)减少开销。

    • 提高响应性(例如 UI 线程 + 后台线程)或实现并行计算。 (0xkishan.medium.com)

  3. 线程与进程的生命周期/状态有哪些?

    • 进程状态:新建 → 就绪 → 运行 → 阻塞/等待 → 终止。

    • 线程状态(视平台而定):新建/可运行 → 运行 → 阻塞/等待 → 终止。

    • 面试中可能问线程的 “新建 (created)/就绪 (runnable)/运行 (running)/阻塞 (blocked)/终止 (terminated)” 状况。 (Indeed)

  4. 什么是多线程 (Multithreading)?与多进程 (Multiprocessing) 有何区别?

    • 多线程:在一个进程中运行多个线程,共享进程资源。

    • 多进程:多个进程运行,各自拥有独立地址空间。

    • 区别:资源开销、内存隔离、通信方式不同。 (finalroundai.com)


2 线程同步与并发安全

  1. 什么是数据竞争(Race Condition)?

    • 当多个线程同时访问同一共享数据,并且至少一个是写操作,且访问不受同步机制保护,则可能出现数据竞争。

    • 导致不可预测结果。

    • 面试中常要求给出例子,比如 counter++ 在多线程中未加锁的场合。

  2. 什么是死锁 (Deadlock)?如何避免?

    • 死锁:两个或多个线程互相等待对方释放资源,从而永久阻塞。

    • 避免方法:

      • 保持加锁顺序一致;

      • 避免锁嵌套或使用递归锁时谨慎;

      • 尽量缩短持锁时间;

      • 使用定时锁、尝试锁(try_lock)等。

    • 面试中经常考察死锁条件(互斥、占用且等待、循环等待、资源不可抢夺)和解决方法。

  3. 什么是线程同步?主要有哪些机制?

    • 同步是控制线程间的执行顺序、防止资源冲突的技术。

    • 常见机制:互斥锁 (mutex)、条件变量 (condition variable)、信号量 (semaphore)、读写锁 (shared_mutex)、原子操作 (atomic) 等。

    • 面试中可能问「互斥锁 vs 读写锁」「条件变量如何工作」「信号量用途」等。

  4. 在 C++ 中如何管理线程安全?有哪些工具或接口?

    • std::mutex, std::lock_guard, std::unique_lock

    • 原子类型 std::atomic<T>

    • 条件变量 std::condition_variable

    • 读写锁 std::shared_mutex(C++17)

    • 线程局部存储 thread_local

    • 面试可延伸问「何时使用互斥锁,何时用原子操作」。

  5. 什么是原子操作 (Atomic operation)?在 C++ 中如何使用?

    • 原子操作:不可分割的操作,执行过程不会被线程切换中断。

    • C++ 中常用 std::atomic<T>

    • 用于简单变量计数或标志,不需要完整锁机制。

    • 面试中可能问 std::atomic 的内存序 (memory_order) 概念、CAS (compare_and_swap) 等。


3 典型题目与深入考点

  1. std::thread 创建线程的方式?线程函数可以接受什么参数?

    • std::thread t(func, arg1, arg2, …);

    • 参数可以是普通函数、成员函数、lambda 表达式、可调用对象。

    • 注意传参方式(拷贝/引用)与线程生命周期管理(join()/detach())。

  2. std::thread::join()detach() 有什么区别?

    • join():主线程等待子线程结束。

    • detach():子线程独立运行,主线程不等待;注意资源管理/线程结束问题。

    • 面试可能问:detach 后如何保证线程资源被清理?何时使用。

  3. 解释 std::lock_guard<std::mutex>std::unique_lock<std::mutex> 的区别。

    • lock_guard:简单、RAII 风格,只负责加锁-解锁,不可延迟解锁。

    • unique_lock:更灵活,可延迟加锁、提前解锁、转移锁所有权、支持 std::condition_variable::wait()

    • 面试可能问为何不用裸 mutex.lock()/unlock() 而用 RAII。

  4. 什么是线程池 (Thread Pool)?为什么使用?

    • 线程池:预先创建若干线程,重复利用线程执行任务,而不是频繁创建销毁线程。

    • 优点:减少线程创建销毁开销、限制线程数、控制资源。

    • 面试可能问自己设计一个线程池的思路。

  5. 读写锁(shared_mutex)与互斥锁有什么区别?在什么场景下使用?

    • 互斥锁:一次只一个线程访问资源。

    • 读写锁:允许多个“读者”同时访问,但“写者”必须独占。

    • 适用于读多写少的场景。

    • 面试可能问“如果大量线程只读一个共享结构,你如何优化同步?”

  6. 线程优先级、亲和性(Affinity)、栈空间如何设置?(嵌入式/系统面试)

    • 线程优先级:操作系统调度时考虑线程优先级。

    • 亲和性:绑定线程到特定 CPU 核,有利于缓存一致性/性能。

    • 栈空间:线程默认栈大小可能不适合嵌入式,应设置合理栈。

    • 面试可能问“在嵌入式系统中你如何创建一个实时线程?用哪 API?需注意什么?”

  7. 对于多个线程修改同一个变量,你会如何处理?

    • 方案:使用互斥锁保护、或者用 std::atomic

    • 面试关注:为啥不直接加锁?性能与延迟考虑。

    • 注意细节:当操作复杂(多个变量或数据结构)时,单个原子变量不足。

  8. 栈内存、堆内存、全局变量在多线程中的区别是什么?

    • 每个线程有自己独立的“栈”(函数调用、局部变量)。

    • 进程堆、全局变量、静态变量在线程之间共享。

    • 面试可能问“线程共享哪些?哪些不共享?”
      (例如你之前提到“线程有自己的栈、程序计数器”)

  9. 优先级反转 (Priority Inversion) 是什么?怎么避免?

    • 高优先级线程等待低优先级线程持有锁,而低优先级线程又被中优先级线程抢占,从而优先级最高的线程被“反转” 卡住。

    • 避免方式:优先级继承 (priority inheritance)、限制锁持有时间、避免锁抢占。

    • 面试中系统/嵌入式较为常见。

  10. 死锁、活锁 (Livelock)、饥饿 (Starvation) 区别?

    • 死锁:线程互相等待资源,永不继续。

    • 活锁:线程不停进行状态改变但没进展(忙等)。

    • 饥饿:线程长期得不到资源,无法执行。

    • 面试中常要求举例、提出解决方案。

  11. C++ 内存模型 (C++11 及以后) 中的 happens-before 关系是什么?为什么重要?

    • 用于定义多线程环境中操作的可见性和顺序保证。

    • std::atomic 操作、锁操作都影响 happens-before 。

    • 面试可能问 memory_order_relaxed vs memory_order_seq_cst 等。

    • 来自高级/系统级面试题。 (aloa.co)

4 针对嵌入式/系统级工程师的补充题目

  1. 在嵌入式系统(Linux/RTOS)中创建线程要注意哪些?

    • 栈大小、优先级、CPU 亲和性。

    • 资源有限,避免大量线程、避免长时间锁。

    • 实时调度策略(比如 SCHED_FIFO / SCHED_RR)与优先级继承。

  2. 进程间通信 (IPC) 和线程间通信有什么不同?

    • 线程间:共享内存;速度快;但需同步。

    • 进程间:一般通过管道、消息队列、共享内存 + 锁、socket 等;资源隔离更强。 (Those Pesky Bugs! Blog)

    • 面试可能问“在你的项目里你为什么选线程而不是进程?”、“什么时候应使用进程而不是线程?”。

  3. 在 C++ 中,如何设置线程栈大小?如何获取线程本地句柄进行平台操作?

    • 对于 std::thread:可以使用 native_handle() 获得底层平台句柄(如 pthread_t 或 Windows HANDLE)。

    • 在 POSIX 上:使用 pthread_attr_setstacksize() 在创建线程时设置栈大小。

    • 面试中可能问“如何在 Linux 上为线程指定特定栈大小?”。

  4. 线程池在嵌入式/高性能系统中的应用?设计思路?

    • 固定线程数、任务队列、任务调度、线程复用。

    • 避免频繁创建/销毁线程开销。

    • 面试可能要求你“设计一个简单的线程池类”。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐