1)锁mutex
2)条件变量
头文件<condiction_variable>
condition_variable cv;
cv.wait(_lock,谓语)//使用谓语检查是否满足唤醒条件,防止假唤醒
using namespace std;
mutex _mutex;
condition_variable cv;
//condition_variable cv2;
int num = 1;
thread th1([&]() {
int i = 10;
while (i--)
{
std::unique_lock<std::mutex> lock(_mutex);
cv.wait(lock, [&]() {
return num == 1;
});
cout << "one" << endl;
num = 2;
cv.notify_one();
}
});
thread th2([&]() {
int i = 10;
while (i--)
{
std::unique_lock<std::mutex> lock(_mutex);
cv.wait(lock, [&]() {
return num == 2;
});
cout << "two" << endl;
num = 1;
cv.notify_one();
}
});
th1.join();
th2.join();
3)并发三剑客, future, promise以及async
async:
不开线程,异步调用一个函数(其实是默认开启后台线程)
int fun_task(int val)
{
int i = 4;
while (i--)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
}
return 12;
}
//异步调用一个函数
int main(int argc,char* argv[])
{
using namespace std;
std::future<int> result = std::async(std::launch::async, fun_task, 4);
for (int i = 0; i < 4; i++)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << i << std::endl;
}
int _val= result.get();
cout << _val << endl;
// 使用 std::async 异步调用 fetchDataFromDB
std::futurestd::string resultFromDB = std::async(std::launch::async, fetchDataFromDB, "Data");
std::launch枚举:
std::launch::deferred:这种策略意味着任务将在调用std::future::get()或std::future::wait()函数时延迟执行。换句话说,任务将在需要结果时同步执行。
std::launch::async 标志来明确表明我们希望函数异步执行。
std::launch::async | std::launch::deferred:(默认值)这种策略是上面两个策略的组合。任务可以在一个单独的线程上异步执行,也可以延迟执行,具体取决于实现。
4)std::promise
std::promise 和 std::future 一起使用,可以实现从一个线程向另一个线程传递值或异常的功能。
void producer(std::promise<int> &&promise) {
// 模拟耗时操作
std::this_thread::sleep_for(std::chrono::seconds(2));
int result = 42;
promise.set_value(result); // 设置值
}
int main() {
// 创建一个 promise 对象
std::promise<int> promise;
// 获取对应的 future 对象
std::future<int> future = promise.get_future();
// 在一个新线程中执行 producer 函数
std::thread t(producer, std::move(promise));
// 继续执行其他操作
std::cout << "Doing some other work..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
// 获取异步任务的结果
try {
int result = future.get(); // 阻塞,直到结果可用
std::cout << "Result: " << result << std::endl;
} catch (const std::exception &e) {
std::cerr << "Exception: " << e.what() << std::endl;
}
// 等待子线程完成
t.join();
return 0;
线程间通信的其他方式:
消息队列如 Boost.Interprocess
共享内存:Boost.Interprocess
5)std::future
包含:
std::future
std::shared_future
std::future::get()/wait()
std::future::get() 是一个阻塞调用,用于获取 std::future 对象表示的值或异常。
如果异步任务还没有完成,get() 会阻塞当前线程,直到任务完成。如果任务已经完成,get() 会立即返回任务的结果
get()只能调用一次
如果有异常,get会抛出
std::future::wait() 也是一个阻塞调用,
如果任务已经完成,wait() 会立即返回。如果任务还没有完成,wait() 会阻塞当前线程,直到任务完成。与 get() 不同,wait() 可以被多次调用
b)获得处理异步任务的结果
std::packaged_task和std::future