c++五分钟搞定异步处理

future的使用

c++11异步操作提供了future相关的类,std::future、std::promise和std::packaged_task,std::future比std::thread高级些,std::future作为异步结果的传输通道,通过get_future()和get()可以很方便的获取线程函数的返回值,std::promise用来包装一个值,将数据和future绑定起来,而std::packaged_task则用来包装一个可调用函数,将函数和future绑定起来,该函数返回值可以在特定时间获得。future是不可以复制的,源码中future( const future& other ) = delete;可以看到拷贝构造器已被删除。

promise与future配合使用

用两个例子供大家理解,第一个在子线程获取主线程的数据,第二个例子为主线程获取子线程数据。

c 复制代码
#include <functional>
#include <future>
#include <iostream>
#include <thread>

using namespace std;

void func(std::future<int>& fut) {
    int x = fut.get();
    cout << "value: " << x << endl;
}

int main() {
    std::promise<int> prom;
    std::future<int> fut = prom.get_future();
    std::thread t(func, std::ref(fut));
    prom.set_value(100);
    t.join();
    return 0;
}

c 复制代码
#include <iostream>
#include <thread>
#include <future>
#include <functional>
#include <string>
using namespace std;
int main()
{
    promise<string> pr;
    thread t2([](promise<string> &p)
              { p.set_value("hello"); 
              this_thread::sleep_for(chrono::seconds(2));
       }, ref(pr));
    future<string> f2 = pr.get_future();
    cout << "f2.get(): " << f2.get() << endl;
    t2.join();
    return 0;
}

需要强调,promise对象必须要通过引用的方式传递,在实例化子线程对象的时候,任务函数的参数是引用类型,那么实参需要放到std::ref()函数中,表示实参的引用传递

packaged_task与future配合使用

arduino 复制代码
#include <iostream>
#include <thread>
#include <future>
#include <functional>
using namespace std;

int main()
{
    function<int(int)> f1 = [](int x)
    {
        return x * 100;
    };
    packaged_task<int(int)> task(f1);

    thread t1(ref(task), 100);

    future<int> f = task.get_future();
    int value = f.get();
    std::cout << "value: " << value << endl;
    t1.join();
    return 0;
}

c 复制代码
#include <functional>
#include <future>
#include <iostream>
#include <thread>

using namespace std;

int func(int in) {
    return in + 1;
}

int main() {
    std::packaged_task<int(int)> task(func);
    std::future<int> fut = task.get_future();
    std::thread(std::move(task), 5).detach();
    cout << "result " << fut.get() << endl;
    return 0;
}

三者之间的关系

future用于访问异步操作的结果,而promise和packaged_task在future高一层,它们内部都有一个future,promise包装的是一个值,packaged_task包装的是一个函数,当需要获取线程中的某个值,可以使用promise,当需要获取线程函数返回值,可以使用packaged_task。

async的使用

async是比future,packaged_task,promise更高级的东西,它是基于任务的异步操作,通过async可以直接创建异步的任务,返回的结果会保存在future中,不需要像packaged_task和promise那么麻烦,关于线程操作应该优先使用async

c 复制代码
#include <functional>
#include <future>
#include <iostream>
#include <thread>

using namespace std;

int func(int in) { return in + 1; }

int main() {
    auto res = std::async(func, 5);
    // res.wait();
    cout << res.get() << endl;
    return 0;
}

async具体语法如下:async(std::launch::async | std::launch::deferred, func, args...);

  • std::launch::async表示任务执行在另一线程
  • std::launch::deferred表示延迟执行任务,调用get或者wait时才会执行,不会创建线程,惰性执行在当前线程。代码说明
c 复制代码
#include <iostream>
#include <future>
#include <chrono>
int computeSomething(int x) {
    std::this_thread::sleep_for(std::chrono::seconds(2));
    return x * x; 
}

int main() {
    std::future<int> resultFuture = std::async(std::launch::async, computeSomething, 5);
    int result = resultFuture.get();
    std::cout << "Result: " << result << std::endl;
    return 0;
}

c 复制代码
#include <iostream>
#include <future>
#include <chrono>
int computeSomething(int x) {
    std::this_thread::sleep_for(std::chrono::seconds(2));
    return x * x;
}

int main() {
    // 使用 std::async 启动异步任务,使用 std::launch::deferred 策略
    std::future<int> resultFuture = std::async(std::launch::deferred, computeSomething, 5);
    int result = resultFuture.get();
    std::cout << "Result: " << result << std::endl;
    return 0;
}

总结

  • std::async:最简单的方式启动异步任务,适合大多数需要异步执行函数并获取结果的场景。最推荐使用
  • std::promise:提供了一种手动控制异步任务结果的方式,适合需要显式设置值或异常的场景。
  • std::packaged_task:提供了将可调用对象包装成任务的能力,适合需要灵活管理任务的场景。
相关推荐
王老师青少年编程1 小时前
2025年12月GESP真题及题解(C++七级): 城市规划
c++·gesp·csp·信奥赛·七级·csp-s·提高组
寻星探路2 小时前
【算法专题】滑动窗口:从“无重复字符”到“字母异位词”的深度剖析
java·开发语言·c++·人工智能·python·算法·ai
我叫袁小陌3 小时前
C++多线程全面详解
开发语言·c++
m0_748250033 小时前
C++ 官方文档与标准
开发语言·c++
matlabgoodboy4 小时前
程序代做python代编程matlab定制代码编写C++代写plc设计java帮做
c++·python·matlab
DYS_房东的猫4 小时前
《 C++ 零基础入门教程》第6章:模板与 STL 算法 —— 写一次,用万次
开发语言·c++·算法
点云SLAM4 小时前
C++ 静态初始化顺序问题(SIOF)和SLAM / ROS 工程实战问题
开发语言·c++·slam·静态初始化顺序问题·工程实战技术·c++static 关键字
pen-ai5 小时前
打通 Python 与 C++ 的参数传递机制
开发语言·c++·python
王老师青少年编程5 小时前
信奥赛C++提高组csp-s之KMP算法详解
c++·kmp·字符串匹配·csp·信奥赛·csp-s·提高组
喵星人工作室5 小时前
C++传说:神明之剑0.4.5装备机制彻底完成
开发语言·c++·游戏