在现代 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
进行线程间的信号传递。 - 高效线程管理:使用 线程池 复用线程,优化性能。