通八洲科技

C++多线程怎么实现?C++ thread库并发编程详解【进阶实战】

日期:2025-12-29 00:00 / 作者:冰火之心
std::thread 实现多线程需关注生命周期、同步与异常安全,核心是协作而非仅启动;创建后必须 join 或 detach,否则析构时程序终止。

std::thread 实现多线程不难,但写对、写稳、写高效需要理解线程生命周期、资源同步和异常安全等关键点。核心不是“怎么启动线程”,而是“怎么让多个线程协作而不打架”。

创建与管理线程:别忘了 join 或 detach

最基础的启动方式是构造 std::thread 对象,传入可调用对象(函数指针、lambda、绑定表达式等):

示例:

void do_work(int id) {
    std::cout << "Thread " << id << " running\n";
}
std::thread t(do_work, 42);  // 启动线程
t.join();  // 等待它结束 —— 必须调用!

⚠️ 关键细节:

共享数据保护:mutex + lock_guard 是黄金组合

多个线程读写同一变量(如全局计数器、容器)时,必须加锁。裸用 std::mutex 容易出错,配合 std::lock_guard 最安全:

std::mutex mtx;
int counter = 0;

void increment() {
    std::lock_guard lock(mtx);  // 构造即加锁,析构即解锁
    ++counter;
}

常见避坑点:

线程间通信:condition_variable 配合 wait/notify

当一个线程需等待另一线程的某个条件成立(如生产者-消费者模型),不能靠轮询,要用条件变量:

std::mutex mtx;
std::queue data_queue;
std::condition_variable cv;
bool ready = false;

// 消费者线程
void consume() {
    std::unique_lock lock(mtx);
    cv.wait(lock, []{ return !data_queue.empty() || ready; }); // 原子检查+等待
    if (!data_queue.empty()) {
        auto val = data_queue.front();
        data_queue.pop();
        std::cout << "Consumed: " << val << "\n";
    }
}

// 生产者线程
void produce(int val) {
    std::lock_guard lock(mtx);
    data_queue.push(val);
    cv.notify_one(); // 唤醒一个等待线程
}

注意:

更高级工具:async、promise/future 和 thread_local

不总需要手动管理线程。现代 C++ 提供更高层抽象:

例如:

thread_local std::mt19937 rng(std::random_device{}()); // 每线程一个随机数生成器
thread_local std::string thread_id = std::to_string(std::this_thread::get_id());

基本上就这些。多线程不是堆满 std::thread 就完事,关键是理清数据归属、明确同步边界、用对 RAII 工具。写并发代码,保守比激进更可靠。