目录

  1. 多线程概述
  2. C++11 线程库 (<thread>)
  3. 线程的创建与管理
  4. 线程同步机制
    • 互斥锁 (std::mutex)
    • 读写锁 (std::shared_mutex)
    • 条件变量 (std::condition_variable)
    • 原子变量 (std::atomic)
  5. 线程池实现
  6. 线程间通信
  7. 线程安全最佳实践
  8. 高级多线程编程
  9. 示例代码
  10. 参考资料

1. 多线程概述

多线程是一种并发编程技术,它允许程序同时执行多个任务,从而提高 CPU 利用率和程序响应能力。在 C++ 中,多线程主要用于:

  • 提高计算密集型任务的性能
  • 处理 I/O 操作(如网络请求、文件读取)
  • 实现并行计算
  • 优化 GUI 应用的响应速度

C++11 标准引入了 <thread> 头文件,使得多线程编程变得更加简单和现代化。


2. C++11 线程库 (<thread>)

C++11 提供了标准线程库 <thread>,可以使用 std::thread 来创建和管理线程。此外,<mutex><condition_variable><atomic> 提供了同步机制,避免数据竞争和并发问题。

常用的多线程相关库:

  • <thread>:线程创建与管理
  • <mutex>:互斥锁,防止多个线程同时访问共享资源
  • <condition_variable>:条件变量,用于线程间的通知机制
  • <atomic>:原子操作,避免竞态条件
  • <future>:异步任务 (std::async)

3. 线程的创建与管理

C++11 通过 std::thread 提供了多种创建线程的方式:

3.1 使用普通函数

#include <iostream>
#include <thread>

void print_message() {
    std::cout << "Hello from thread!" << std::endl;
}

int main() {
    std::thread t(print_message); // 创建线程
    t.join(); // 等待线程执行完成
    return 0;
}

解释

  • std::thread t(print_message); 创建线程 t 并执行 print_message 函数。
  • t.join(); 主线程等待 t 结束,防止主程序退出时 t 仍在运行。

3.2 使用 Lambda 表达式

#include <iostream>
#include <thread>

int main() {
    std::thread t([]() {
        std::cout << "Lambda thread running!" << std::endl;
    });
    t.join();
    return 0;
}

使用 Lambda 使代码更加简洁。

3.3 使用成员函数

#include <iostream>
#include <thread>

class Worker {
public:
    void do_work() {
        std::cout << "Worker thread is running!" << std::endl;
    }
};

int main() {
    Worker worker;
    std::thread t(&Worker::do_work, &worker);
    t.join();
    return 0;
}

3.4 detach() 方法

std::thread t(print_message);
t.detach(); // 让线程在后台运行

detach() 让线程独立运行,主线程不会等待它。但要注意,主线程结束后被 detach 的线程仍然可能访问已销毁的资源,容易造成错误。


4. 线程同步机制

4.1 互斥锁 (std::mutex)

多个线程访问共享数据时可能会发生竞态条件(Race Condition)。std::mutex 用于同步线程对共享资源的访问。

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

std::mutex mtx;

void print_message(int id) {
    std::lock_guard<std::mutex> lock(mtx);
    std::cout << "Thread " << id << " is running!" << std::endl;
}

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

解释

  • std::lock_guard<std::mutex> lock(mtx); 自动加锁和解锁,防止数据竞争。

4.2 读写锁 (std::shared_mutex)

C++17 提供了 std::shared_mutex,适用于读多写少的场景。

#include <iostream>
#include <thread>
#include <shared_mutex>

std::shared_mutex rw_lock;

void read() {
    std::shared_lock<std::shared_mutex> lock(rw_lock);
    std::cout << "Reading data..." << std::endl;
}

void write() {
    std::unique_lock<std::shared_mutex> lock(rw_lock);
    std::cout << "Writing data..." << std::endl;
}

int main() {
    std::thread t1(read);
    std::thread t2(write);
    t1.join();
    t2.join();
    return 0;
}


4.3 条件变量 (std::condition_variable)

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

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

void worker() {
    std::unique_lock<std::mutex> lock(mtx);
    cv.wait(lock, []{ return ready; }); // 等待主线程通知
    std::cout << "Worker thread running!" << std::endl;
}

int main() {
    std::thread t(worker);
    std::this_thread::sleep_for(std::chrono::seconds(1));
    
    {
        std::lock_guard<std::mutex> lock(mtx);
        ready = true;
    }
    
    cv.notify_one(); // 通知 worker 线程继续执行
    t.join();
    return 0;
}


5. 线程池实现

线程池通过预创建线程来提高性能。

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

class ThreadPool {
public:
    ThreadPool(size_t threads);
    ~ThreadPool();
    void enqueue(std::function<void()> task);

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

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

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

ThreadPool::~ThreadPool() {
    {
        std::lock_guard<std::mutex> lock(queue_mutex);
        stop = true;
    }
    condition.notify_all();
    for (std::thread &worker : workers) worker.join();
}

int main() {
    ThreadPool pool(4);
    pool.enqueue([]() { std::cout << "Task executed!" << std::endl; });
    return 0;
}


6. 参考资料