一 概述
std::thread 是 C++11 引入的线程库,用于创建和管理多线程程序。
二 基本用法
1 创建线程
#include <iostream>
#include <thread>
// 普通函数作为线程函数
void hello() {
std::cout << "Hello from thread!" << std::endl;
}
// Lambda表达式作为线程函数
auto lambda = []() {
std::cout << "Hello from lambda thread!" << std::endl;
};
// 带参数的函数
void print_number(int num) {
std::cout << "Number: " << num << std::endl;
}
int main() {
// 创建线程
std::thread t1(hello);
std::thread t2(lambda);
std::thread t3(print_number, 42);
// 等待线程完成
t1.join();
t2.join();
t3.join();
return 0;
}
2 类成员函数作为线程函数
#include <iostream>
#include <thread>
class MyClass {
public:
void member_func(int x) {
std::cout << "Member function: " << x << std::endl;
}
static void static_func() {
std::cout << "Static member function" << std::endl;
}
};
int main() {
MyClass obj;
// 调用成员函数
std::thread t1(&MyClass::member_func, &obj, 100);
// 调用静态成员函数
std::thread t2(&MyClass::static_func);
t1.join();
t2.join();
return 0;
}
```
二 线程管理
1 join() 和 detach()
#include <iostream>
#include <thread>
#include <chrono>
void worker() {
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Worker thread finished" << std::endl;
}
int main() {
std::thread t1(worker);
if (t1.joinable()) {
// join() - 等待线程结束
t1.join();
}
std::thread t2(worker);
if (t2.joinable()) {
// detach() - 分离线程(后台运行)
t2.detach();
}
// 注意:分离后不能再 join()
// t2.join(); // 错误!
// 主线程等待,确保分离的线程有机会执行
std::this_thread::sleep_for(std::chrono::seconds(2));
return 0;
}
2 获取线程ID
#include <iostream>
#include <thread>
void print_id() {
std::cout << "Thread ID: " << std::this_thread::get_id() << std::endl;
}
int main() {
std::thread t1(print_id);
std::thread t2(print_id);
std::cout << "Main thread ID: " << std::this_thread::get_id() << std::endl;
std::cout << "t1 ID: " << t1.get_id() << std::endl;
t1.join();
t2.join();
return 0;
}
三 传递参数
1 按值传递
#include <iostream>
#include <thread>
void func(int a, std::string b, double c) {
std::cout << "a=" << a << ", b=" << b << ", c=" << c << std::endl;
}
int main() {
std::thread t(func, 1, "hello", 3.14);
t.join();
return 0;
}
2 按引用传递
#include <iostream>
#include <thread>
#include <functional> // 需要 std::ref
void modify_value(int& x) {
x = 100;
}
int main() {
int value = 0;
// 使用 std::ref 传递引用
std::thread t(modify_value, std::ref(value));
t.join();
std::cout << "Value after modification: " << value << std::endl; // 输出 100
return 0;
}
3 传递指针
#include <iostream>
#include <thread>
void process_array(int* arr, int size) {
for (int i = 0; i < size; ++i) {
arr[i] *= 2;
}
}
int main() {
int arr[] = {1, 2, 3, 4, 5};
std::thread t(process_array, arr, 5);
t.join();
for (int num : arr) {
std::cout << num << " "; // 输出: 2 4 6 8 10
}
std::cout << std::endl;
return 0;
}
四 线程同步
1 使用互斥锁
#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
std::mutex mtx;
int counter = 0;
void increment() {
for (int i = 0; i < 10000; ++i) {
mtx.lock(); // 上锁
++counter;
mtx.unlock(); // 解锁
}
}
int main() {
std::thread t1(increment);
std::thread t2(increment);
t1.join();
t2.join();
std::cout << "Counter value: " << counter << std::endl; // 应该是 20000
return 0;
}
2 使用 RAII 风格的锁
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
int counter = 0;
void increment() {
for (int i = 0; i < 10000; ++i) {
std::lock_guard<std::mutex> lock(mtx); // 自动加锁解锁
++counter;
}
}
int main() {
std::thread t1(increment);
std::thread t2(increment);
t1.join();
t2.join();
std::cout << "Counter value: " << counter << std::endl;
return 0;
}
五 线程移动
#include <iostream>
#include <thread>
#include <vector>
void worker(int id) {
std::cout << "Worker " << id << " started" << std::endl;
}
int main() {
// 线程对象不能复制,只能移动
std::thread t(worker, 1);
// 移动语义
std::thread t2 = std::move(t);
// t 现在为空,不能再使用
// t.join(); // 错误!
if (t2.joinable()) {
t2.join();
}
// 线程向量
std::vector<std::thread> threads;
for (int i = 0; i < 5; ++i) {
// 使用 emplace_back 直接构造
threads.emplace_back(worker, i);
}
// 等待所有线程完成
for (auto& t : threads) {
if (t.joinable()) {
t.join();
}
}
return 0;
}
六 实用技巧
1 使用 packaged_task
#include <iostream>
#include <thread>
#include <future>
#include <functional>
int compute(int x, int y) {
return x * y;
}
int main() {
std::packaged_task<int(int, int)> task(compute);
std::future<int> result = task.get_future();
// 在新线程中执行任务
std::thread t(std::move(task), 6, 7);
// 获取结果
std::cout << "Result: " << result.get() << std::endl;
t.join();
return 0;
}
2 线程睡眠
#include <iostream>
#include <thread>
#include <chrono>
void slow_worker() {
std::cout << "Worker starting..." << std::endl;
// 睡眠 2 秒
std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << "Worker finished!" << std::endl;
}
int main() {
std::thread t(slow_worker);
t.join();
return 0;
}
七 注意事项
1 资源管理:确保线程在析构前被 join() 或 detach()。
2 数据竞争:使用适当的同步机制。
3 异常安全:线程函数中的异常需要处理。
4 性能考虑:避免创建过多线程。
5 平台差异:线程行为在不同操作系统上可能略有不同。
八 完整示例
#include <iostream>
#include <thread>
#include <vector>
#include <mutex>
#include <chrono>
class ThreadPool {
private:
std::vector<std::thread> workers;
std::mutex mtx;
public:
void add_worker(int id) {
workers.emplace_back([this, id]() {
{
std::lock_guard<std::mutex> lock(mtx);
std::cout << "Worker " << id << " started" << std::endl;
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
{
std::lock_guard<std::mutex> lock(mtx);
std::cout << "Worker " << id << " finished" << std::endl;
}
});
}
void wait_all() {
for (auto& t : workers) {
if (t.joinable()) {
t.join();
}
}
}
};
int main() {
ThreadPool pool;
// 创建 10 个工作线程
for (int i = 0; i < 10; ++i) {
pool.add_worker(i);
}
// 等待所有线程完成
pool.wait_all();
std::cout << "All workers finished!" << std::endl;
return 0;
}
这个示例展示了 std::thread 的主要用法。实际使用时,建议考虑使用更高级的抽象,如 C++17 的 std::jthread 或第三方线程池库。