• C++异步调用方法


    C++之future和promise

    future和promise的作用是在不同线程之间传递数据。使用指针也可以完成数据的传递,但是指针非常危险,因为互斥量不能阻止指针的访问;而且指针的方式传递的数据是固定的,如果更改数据类型,那么还需要更改有关的接口,比较麻烦;promise支持泛型的操作,更加方便编程处理。

    假设线程1需要线程2的数据,那么组合使用方式如下:

    线程1初始化一个promise对象和一个future对象,promise传递给线程2,相当于线程2对线程1的一个承诺;future相当于一个接受一个承诺,用来获取未来线程2传递的值
    线程2获取到promise后,需要对这个promise传递有关的数据,之后线程1的future就可以获取数据了。
    如果线程1想要获取数据,而线程2未给出数据,则线程1阻塞,直到线程2的数据到达。

    future对象是std::async、std::promise、std::packaged_task的底层对象,用来传递其他线程中操作的数据结果。

    std::promise的作用就是提供一个不同线程之间的数据同步机制,它可以存储一个某种类型的值,并将其传递给对应的future, 即使这个future不在同一个线程中也可以安全的访问到这个值。

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. void thread_set_promise(std::promise<int>& promiseObj) {
    8. std::cout << "In a thread, making data...\n";
    9. std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    10. promiseObj.set_value(35);
    11. std::cout << "Finished\n";
    12. }
    13. int main() {
    14. std::promise<int> promiseObj;
    15. std::future<int> futureObj = promiseObj.get_future();
    16. std::thread t(&thread_set_promise, std::ref(promiseObj));
    17. std::cout << futureObj.get() << std::endl;
    18. t.join();
    19. system("pause");
    20. return 0;
    21. }

     

    async(高级封装future和thread)

    std::future可以从异步任务中获取结果,一般与std::async配合使用,std::async用于创建异步任务,实际上就是创建一个线程执行相应任务。

    std::async就是异步编程的高级封装,封装了std::future的操作,基本上可以代替std::thread 的所有事情。

    std::async的操作,其实相当于封装了std::promise、std::packaged_task加上std::thread。

    1. #include // std::cout
    2. #include // std::async, std::future
    3. #include // std::chrono::milliseconds
    4. bool is_prime (int x) {
    5. for (int i=2; iif (x%i==0) return false;
    6. return true;
    7. }
    8. int main ()
    9. {
    10. // call function asynchronously:
    11. std::future<bool> fut = std::async (is_prime,444444443);
    12. // do something while waiting for function to set future:
    13. std::cout << "checking, please wait";
    14. std::chrono::milliseconds span (100);
    15. while (fut.wait_for(span)==std::future_status::timeout)
    16. std::cout << '.' << std::flush;
    17. bool x = fut.get(); // retrieve return value
    18. std::cout << "\n444444443 " << (x?"is":"is not") << " prime.\n";
    19. return 0;
    20. }

    std::async会首先创建线程执行is_prime(444444443), 任务创建之后,std::async立即返回一个std::future对象。

     主线程既可使用std::future::get获取结果,如果调用过程中,任务尚未完成,则主线程阻塞至任务完成。

     主线程也可使用std::future::wait_for等待结果返回,wait_for可设置超时时间,如果在超时时间之内任务完成,则返回std::future_status::ready状态;如果在超时时间之内任务尚未完成,则返回std::future_status::timeout状态。

    reference:C++之future和promise

  • 相关阅读:
    Golang 发送邮件
    【论文】attention is all you need
    STM32CubeMX环境安装(保姆级)
    java电商系统怎么设计秒杀?
    复杂AB实验
    How to Config VS2022
    「二叉树与递归的一些框架思维」「1464. 数组中两元素的最大乘积」(每日刷题打卡Day33)[C++]
    第80步 时间序列建模实战:GRNN回归建模
    RK3568平台开发系列讲解(驱动基础篇)驱动模块传参
    结构开发笔记(一):外壳IP防水等级与IP防水铝壳体初步选型
  • 原文地址:https://blog.csdn.net/dayslrk/article/details/130904969