目录
- 多线程概述
- C++11 线程库 (
<thread>
) - 线程的创建与管理
- 线程同步机制
- 互斥锁 (
std::mutex
) - 读写锁 (
std::shared_mutex
) - 条件变量 (
std::condition_variable
) - 原子变量 (
std::atomic
)
- 互斥锁 (
- 线程池实现
- 线程间通信
- 线程安全最佳实践
- 高级多线程编程
- 示例代码
- 参考资料
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;
}
发表回复