C++ 线程编程:std::thread

在现代 C++ 开发中,多线程编程是提高程序并发能力、加速计算和优化性能的重要手段。C++11 及以上版本引入了 std::thread,让开发者可以更加方便地创建和管理线程。


在这里插入图片描述

1. C++ 线程的创建

在 C++ 中,可以使用 std::thread 来创建线程,并让它执行一个函数或 lambda 表达式。

1.1 使用普通函数创建线程

#include <iostream>
#include <thread>

void task() {
    
    
    std::cout << "[子线程] 线程启动...\n";
    std::this_thread::sleep_for(std::chrono::seconds(2));  // 模拟工作
    std::cout << "[子线程] 线程执行完成!\n";
}

int main() {
    
    
    std::cout << "[主线程] 创建子线程...\n";
    std::thread t(task);  // 创建线程并执行 task 函数
    t.join();  // 等待线程完成
    std::cout << "[主线程] 子线程已结束,继续执行主线程代码。\n";
    return 0;
}

代码解析

  • std::thread t(task); 创建并运行 task 线程。
  • t.join(); 主线程会等待子线程执行完毕,然后继续运行。

示例输出

[主线程] 创建子线程...
[子线程] 线程启动...
(等待 2 秒)
[子线程] 线程执行完成!
[主线程] 子线程已结束,继续执行主线程代码。

2. detach() 让线程在后台运行

detach() 让线程与主线程分离,在后台独立运行。

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

void backgroundTask() {
    
    
    std::cout << "[子线程] 线程启动...\n";
    std::this_thread::sleep_for(std::chrono::seconds(3));
    std::cout << "[子线程] 线程执行完成!\n";
}

int main() {
    
    
    std::cout << "[主线程] 创建子线程...\n";
    std::thread t(backgroundTask);
    t.detach();  // 使子线程在后台运行
    std::cout << "[主线程] 继续执行,不等待子线程!\n";
    
    std::this_thread::sleep_for(std::chrono::seconds(5));  // 保持主线程运行,确保子线程能执行
    std::cout << "[主线程] 主线程结束。\n";
    return 0;
}

示例输出

[主线程] 创建子线程...
[主线程] 继续执行,不等待子线程!
(等待 3 秒)
[子线程] 线程启动...
[子线程] 线程执行完成!
(等待 2 秒)
[主线程] 主线程结束。

注意

  • detach() 后,主线程不会等待子线程执行完毕。
  • 如果主线程提前退出,子线程可能还未执行完毕!
  • 解决方案:让 main() 等待一段时间,确保子线程有机会执行。

3. 线程同步(std::mutex

多个线程访问共享资源时,必须使用同步机制,防止数据竞争。

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

std::mutex mtx;  // 互斥锁
int counter = 0; // 共享资源

void increaseCounter(int id) {
    
    
    for (int i = 0; i < 5; ++i) {
    
    
        std::lock_guard<std::mutex> lock(mtx);  // 自动管理锁
        counter++;
        std::cout << "[线程 " << id << "] 计数器值: " << counter << "\n";
        std::this_thread::sleep_for(std::chrono::milliseconds(200));  // 模拟工作
    }
}

int main() {
    
    
    std::cout << "[主线程] 启动两个子线程...\n";
    std::thread t1(increaseCounter, 1);
    std::thread t2(increaseCounter, 2);

    t1.join();
    t2.join();

    std::cout << "[主线程] 最终计数器值: " << counter << "\n";
    return 0;
}

示例输出

[主线程] 启动两个子线程...
[线程 1] 计数器值: 1
[线程 2] 计数器值: 2
...
[主线程] 最终计数器值: 10

关键点

  • std::mutex 互斥锁保证多个线程不会同时修改 counter,防止数据竞争。

4. 线程间通信(std::condition_variable

线程间可以使用 std::condition_variable 进行信号通信。

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

std::mutex mtx;
std::condition_variable cv;
bool ready = false;  // 共享状态

void worker() {
    
    
    std::unique_lock<std::mutex> lock(mtx);
    std::cout << "[子线程] 等待主线程的信号...\n";
    cv.wait(lock, [] {
    
     return ready; });  // 等待 ready 变为 true
    std::cout << "[子线程] 收到信号,开始工作!\n";
}

int main() {
    
    
    std::thread t(worker);
    
    std::this_thread::sleep_for(std::chrono::seconds(2));
    {
    
    
        std::lock_guard<std::mutex> lock(mtx);
        ready = true;  // 设置共享状态
    }
    std::cout << "[主线程] 发送信号,通知子线程!\n";
    cv.notify_one();  // 唤醒子线程

    t.join();
    std::cout << "[主线程] 结束。\n";
    return 0;
}

5. 线程池

线程池用于管理多个线程,提高并发性能。

#include <iostream>
#include <vector>
#include <thread>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <functional>

class ThreadPool {
    
    
public:
    ThreadPool(size_t numThreads) {
    
    
        for (size_t i = 0; i < numThreads; ++i) {
    
    
            workers.emplace_back([this] {
    
    
                while (true) {
    
    
                    std::function<void()> task;
                    {
    
    
                        std::unique_lock<std::mutex> lock(queueMutex);
                        condition.wait(lock, [this] {
    
     return !tasks.empty() || stop; });
                        if (stop && tasks.empty()) return;
                        task = std::move(tasks.front());
                        tasks.pop();
                    }
                    task();
                }
            });
        }
    }

    void enqueue(std::function<void()> task) {
    
    
        {
    
    
            std::lock_guard<std::mutex> lock(queueMutex);
            tasks.push(std::move(task));
        }
        condition.notify_one();
    }

    ~ThreadPool() {
    
    
        stop = true;
        condition.notify_all();
        for (std::thread &worker : workers)
            worker.join();
    }

private:
    std::vector<std::thread> workers;
    std::queue<std::function<void()>> tasks;
    std::mutex queueMutex;
    std::condition_variable condition;
    bool stop = false;
};

int main() {
    
    
    ThreadPool pool(4);
    pool.enqueue([] {
    
     std::cout << "任务1执行\n"; });
    pool.enqueue([] {
    
     std::cout << "任务2执行\n"; });
    std::this_thread::sleep_for(std::chrono::seconds(1));
    return 0;
}

总结

  • 线程管理join()(同步),detach()(后台运行)。
  • 线程同步:使用 std::mutex 防止数据竞争。
  • 线程通信:使用 std::condition_variable 进行线程间的信号传递。
  • 高效线程管理:使用 线程池 复用线程,优化性能。