C++11 标准库引入了对多线程编程的支持,使得开发者能够以更加标准化的方式创建和管理线程。主要的线程管理方式是通过 std::thread 类,它可以用来创建、启动和管理线程。下面我将详细介绍如何使用 C++ 标准库创建线程的方法,以及其他一些相关的工具类和概念。
1. 使用 std::thread 创建线程
std::thread 是 C++ 标准库中用于创建和管理线程的类。可以用来启动独立线程来执行某些任务,任务可以是函数、成员函数或 lambda 表达式。
#include <thread>
#include <iostream>
void threadFunction() {
std::cout << "Hello from thread function!" << std::endl;
}
int main() {
// 创建一个线程执行函数
std::thread t(threadFunction);
// 等待线程结束
t.join(); // join() 方法等待线程执行结束
return 0;
}
在这个例子中:
- 使用 std::thread t(threadFunction); 创建了一个新的线程来执行 threadFunction。
- 线程对象 t 使用 join() 方法等待其完成,join() 会阻塞主线程,直到线程 t 结束。
线程分离 (detach)
可以选择使用 detach() 来将线程与主线程分离,从而使其在后台运行。分离的线程一旦开始执行,将无法再与主线程同步。
#include <thread>
#include <iostream>
void threadFunction()
{
std::cout << "Detached thread is running." << std::endl;
}
int main()
{
std::thread t(threadFunction);
t.detach(); // 分离线程,允许它在后台运行
std::cout << "Main thread is ending." << std::endl;
return 0;
}
使用 detach() 后,线程会在后台独立运行,主线程不会等待它结束,需要注意的是,分离线程在结束后主线程无法再管理其状态,因此需要确保线程资源能够得到妥善清理。
2. 使用 lambda 表达式创建线程
可以使用 lambda 表达式来创建线程,这样可以直接在线程内定义任务逻辑,非常灵活。
#include <thread>
#include <iostream>
int main() {
// 使用 lambda 表达式创建线程
std::thread t([] {
std::cout << "Hello from lambda thread!" << std::endl;
});
t.join(); // 等待线程结束
return 0;
}
在这个例子中,lambda 表达式被直接传递给 std::thread 的构造函数,创建了一个执行该 lambda 的线程。这种方式简洁易用,尤其适用于简单的任务。
3. 使用类的成员函数作为线程
std::thread 也可以用来执行类的成员函数,但是需要传递成员函数指针和对象实例来创建线程。
#include <thread>
#include <iostream>
class MyClass {
public:
void memberFunction() {
std::cout << "Hello from member function!" << std::endl;
}
};
int main() {
MyClass myObject;
// 使用成员函数创建线程,需要传递对象实例
std::thread t(&MyClass::memberFunction, &myObject);
t.join(); // 等待线程结束
return 0;
}
在这个例子中:
- 使用 &MyClass::memberFunction 获取成员函数的指针,并使用 &myObject 传递对象实例,创建了一个执行成员函数的线程。
- 注意成员函数需要通过对象实例来调用,因而需要传递对象的指针 &myObject。
4. 使用 std::async 创建任务
std::async 提供了另一种方式来启动并发任务,它返回一个 std::future,可以在未来获取线程任务的结果。
#include <future>
#include <iostream>
int threadFunction() {
return 8888; // 线程的返回值
}
int main()
{
// 使用 std::async 创建并发任务
std::future<int> result = std::async(std::launch::async, threadFunction);
// 获取线程任务的返回值
int value = result.get();
std::cout << "Result from thread: " << value << std::endl;
return 0;
}
在这个例子中:
- 使用 std::async(std::launch::async, threadFunction) 来创建并启动一个并发任务。
- std::future<int> 用于获取线程任务的结果,通过 result.get() 可以等待任务完成并获取返回值。
5. 传递参数给线程函数
std::thread 的构造函数支持传递参数,可以将参数传递给线程函数。参数可以是值类型、引用类型或者其他数据类型。
#include <thread>
#include <iostream>
void threadFunction(int value, const std::string &message) {
std::cout << "Value: " << value << ", Message: " << message << std::endl;
}
int main() {
int value = 42;
std::string message = "Hello from thread";
// 传递参数给线程
std::thread t(threadFunction, value, std::ref(message));
t.join(); // 等待线程结束
return 0;
}
在这个例子中:
- 线程函数 threadFunction 需要两个参数:一个整数和一个字符串。
- 使用 std::ref(message) 传递引用参数,确保线程内对该参数的修改可以反映到主线程中。
6.总结
- std::thread:是 C++ 标准库中创建线程的基础类,支持创建线程、传递参数、调用类成员函数等。
- lambda 表达式:可以直接使用 lambda 表达式创建线程,非常方便灵活。
- 传递参数:可以通过 std::thread 的构造函数向线程函数传递参数,包括值传递和引用传递。
- 生命周期管理:创建线程后,需要使用 join() 或 detach() 管理线程的生命周期,否则程序可能会抛出异常。
- std::async:提供了一种更高级的方式来启动并发任务,并通过 std::future 获取返回结果,适合需要获取任务结果的场景。
std::thread 和 std::async 是 C++ 标准库提供的两种主要方式来创建和管理线程,std::thread 提供了更底层的控制,而 std::async 则提供了一种更高级、自动管理的方式。根据具体的需求和使用场景,可以灵活选择最合适的方式来实现多线程编程。
标签:std,thread,创建,C++,线程,async,include From: https://blog.csdn.net/qq_27438159/article/details/143817414