1. C++11线程基础与std::thread入门
现代C++多线程编程的核心工具就是std::thread。这个类在C++11标准中引入,彻底改变了C++开发者处理并发任务的方式。与传统的pthread或Windows API相比,std::thread提供了更高层次的抽象,让多线程编程变得更加直观和安全。
创建一个线程最基本的语法是构造一个std::thread对象,传入可调用对象(函数、lambda表达式等)及其参数。下面这个简单示例展示了最基本的线程创建和等待:
cpp复制#include <iostream>
#include <thread>
void print_number(int num) {
std::cout << "Number: " << num << std::endl;
}
int main() {
std::thread worker(print_number, 42);
worker.join();
std::cout << "Main thread continues..." << std::endl;
return 0;
}
关键点:join()会阻塞当前线程,直到worker线程执行完毕。如果不调用join()或detach(),程序终止时会调用std::terminate()。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 线程参数传递的深度解析
2.1 值传递与引用传递
默认情况下,std::thread的参数是按值传递的。这意味着线程函数接收的是参数的副本。如果需要传递引用,必须使用std::ref或std::cref包装:
cpp复制void modify_string(std::string& str) {
str += " modified";
}
int main() {
std::string data = "original";
std::thread t1(modify_string, std::ref(data));
t1.join();
std::cout << data << std::endl; // 输出:"original modified"
}
常见陷阱:直接传递引用而不使用std::ref会导致编译错误,因为线程构造函数会尝试复制引用本身而非被引用的对象。
2.2 移动语义与线程参数
对于不可复制但可移动的对象(如unique_ptr),可以使用std::move:
cpp复制void process_data(std::unique_ptr<int> ptr) {
std::cout << *ptr << std::endl;
}
int main() {
auto ptr = std::make_unique<int>(42);
std::thread t(process_data, std::move(ptr));
t.join();
// 此时ptr已经是nullptr
}
3. Lambda表达式与线程的完美结合
Lambda表达式是现代C++中创建线程最常用的方式,它允许我们直接在创建线程的
