c++ 多线程
https://blog.csdn.net/sjc_0910/article/details/118861539
unique_lock 和 lock_guard
多线程是一种实现并发处理的有效方式,C++11开始引入了<thread>
库,使得多线程编程更加容易和高效。以下是C++中多线程编程的一些主要内容:
-
线程的创建:在C++中,可以使用
std::thread
类来创建一个新的线程。例如:#include <iostream> #include <thread> void function_1() { std::cout << "Hello, World!" << std::endl; } int main() { std::thread thread_1(function_1); // 创建一个新的线程 thread_1.join(); // 等待线程结束 return 0; }
-
线程同步:当多个线程需要访问共享数据时,就需要进行线程同步以避免数据竞争。C++提供了多种同步机制,如
std::mutex
、std::lock_guard
、std::unique_lock
等。 -
数据传递:可以使用
std::async
、std::future
、std::promise
等机制在线程之间传递数据。 -
异常处理:如果线程函数抛出一个未捕获的异常,
std::terminate
会被调用,这将导致程序的异常终止。为了避免这种情况,可以在线程函数中使用try/catch
块来捕获和处理异常。
在C++多线程编程中,数据传递是一个重要的问题。以下是一些常见的数据传递方式:
-
通过函数参数传递:当创建一个新的线程时,可以通过函数参数将数据传递给线程函数。例如:
void thread_function(int x) { // 在这里使用x } int main() { int data = 42; std::thread t(thread_function, data); t.join(); return 0; }
在这个例子中,我们将
data
作为参数传递给了thread_function
。 -
通过全局变量传递:所有线程都可以访问全局变量,因此全局变量可以用于在线程之间传递数据。但是,需要注意的是,如果多个线程同时访问和修改全局变量,可能会导致数据竞争。
-
通过
std::promise
和std::future
传递:std::promise
和std::future
是C++11引入的两个类,可以用于在线程之间传递数据4。你可以在一个线程中设置std::promise
的值,然后在另一个线程中获取这个值4。 -
通过
std::async
传递:std::async
是一个函数模板,可以用于创建一个异步任务,并返回一个std::future
对象5。这个std::future
对象可以用于获取异步任务的结果5。 -
通过
std::mutex
和std::lock_guard
进行同步:在多线程编程中,当多个线程需要访问共享数据时,就需要进行线程同步以避免数据竞争2。C++提供了多种同步机制,如std::mutex
、std::lock_guard
、std::unique_lock
等2。
std::promise
和std::future
是C++11引入的两个类,它们提供了一种在不同线程之间传递数据的机制。
-
std::promise:
std::promise
对象可以保存某一类型T的值,该值可被std::future
对象读取(可能在另外一个线程中),因此std::promise
提供了一种线程同步的手段。在std::promise
对象构造时可以和一个共享状态(通常是std::future
)相关联,并可以在相关联的共享状态上保存一个类型为T的值。std::promise
对象是异步Provider,它可以在某一时刻设置共享状态的值。 -
std::future:
std::future
对象可以异步返回共享状态的值,或者在必要的情况下阻塞调用者并等待共享状态标志变为ready,然后才能获取共享状态的值。
以下是一个使用std::promise
和std::future
的C++示例1:
#include <iostream>
#include <thread>
#include <future>
void print_int(std::future<int>& fut) {
int x = fut.get(); // 获取共享状态的值.
std::cout << "value: " << x << '\n'; // 打印 value: 10.
}
int main() {
std::promise<int> prom; // 生成一个 std::promise<int> 对象.
std::future<int> fut = prom.get_future(); // 和 future 关联.
std::thread t(print_int, std::ref(fut)); // 将 future 交给另外一个线程t.
prom.set_value(10); // 设置共享状态的值, 此处和线程t保持同步.
t.join();
return 0;
}
在这个示例中,我们首先创建了一个std::promise
对象和一个std::future
对象,然后在一个新的线程中使用std::future
对象来获取std::promise
对象设置的值。
当然,这是一个使用std::async
的简单示例:
#include <iostream>
#include <future>
// 一个简单的函数,用于计算斐波那契数列的第n项
int fibonacci(int n) {
if (n <= 1) {
return n;
} else {
return fibonacci(n - 1) + fibonacci(n - 2);
}
}
int main() {
// 使用std::async启动一个异步任务
std::future<int> fut = std::async(fibonacci, 10);
// 获取异步任务的结果
int res = fut.get();
// 输出结果
std::cout << "The 10th Fibonacci number is " << res << std::endl;
return 0;
}
在这个示例中,我们创建了一个异步任务来计算斐波那契数列的第10项。std::async
函数返回一个std::future
对象,我们可以使用get
方法从中获取异步任务的结果。这个示例展示了如何使用std::async
进行简单的异步编程。注意,std::async
的使用方式可能会根据具体的编程需求而有所不同。例如,你可能需要处理std::future
的异常,或者使用不同的启动策略等。这个示例只是展示了std::async
的基本用法。在实际的编程中,你可能需要根据具体的需求来调整代码。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)