当前位置: 首页 > article >正文

【从零实现Json-Rpc框架】- 第三方库介绍 - fature篇

📢博客主页:https://blog.csdn.net/2301_779549673
📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson
📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
📢本文由 JohnKi 原创,首发于 CSDN🙉
📢未来很长,值得我们全力奔赴更美好的生活✨

在这里插入图片描述

在这里插入图片描述

文章目录

  • 📢前言
  • 🏳️‍🌈1 std::future
    • 1.1 介绍
    • 1.2 应用场景
  • 🏳️‍🌈 2 用法示例
    • 2.1 使用 std::async关联异步任务
    • 2.2 异步执行std::packaged_task任务
    • 2.3 使用std::promise和std::future配合
  • 👥总结


📢前言

紧接上回,接下来笔者将介绍rpc框架的最重要的三个第三方库,方便大家理解

这回是 fature


🏳️‍🌈1 std::future

1.1 介绍

std::future是C++11标准库中的一个模板类,它表示一个异步操作的结果。当我们在多线程编程中使用异步任务时,std::future可以帮助我们在需要的时候获取任务的执行结果。

std::future的一个重要特性是能够阻塞当前线程,直到异步操作完成,从而确保我们在获取结果时不会遇到未完成的操作。

1.2 应用场景

异步任务:当我们需要在后台执行一些耗时操作时,如网络请求或计算密集型任务等,std:future可以用来表示这些异步任务的结果。通过将任务与主线程分离,我们可以实现任务的并行处理,从而提高程序的执行效率

并发控制:在多线程编程中,我们可能需要等待某些任务完成后才能继续执行其他操作。通过使用std::future,我们可以实现线程之间的同步,确保任务完成后再获取结果并继续执行后续操作

结果获取:std::future提供了一种安全的方式来获取异步任务的结果。我们可以使用std::future:get()函数来获取任务的结果,此函数会阻塞当前线程,直到异步操作完成。这样,在调用get()函数时,我们可以确保已经获取到了所需的结果

🏳️‍🌈 2 用法示例

在这里插入图片描述

2.1 使用 std::async关联异步任务

std::async是一种将任务与std::future关联的简单方法。它创建并运行一个异步任务,并返回一个与该任务结果关联的std::future对象。默认情况下,std:async是否启动一个新线程,或者在等待future时,任务是否同步运行都取决于你给的 参数。这个参数为std::launch类型:

std:.launch::deferred 表明该函数会被延迟调用,直到在future上调用get()或者wait()才会开始。执行任务

std::launch::async表明函数会在自己创建的线程上运行。

std::launch::deferred std::launch:async内部通过系统等条件自动选择策略。

#include <iostream>
#include <future>
#include <thread>    // [!] 必须包含此头文件
#include <chrono>    // [!] 必须包含此头文件


int Add(int num1, int num2){
    return num1 + num2;
}


int main(){
        // async(launch __policy, _Fn&& __fn, _Args&&... __args)
            // __policy:指定策略,可以是launch::async或launch::deferred,默认为launch::async
                // launch::async:异步执行,内部创建一个线程执行函数,函数运行结果通过future获取
                // launch::deferred:延迟执行,获取结果的时候再去执行任务
            // _Fn&& __fn:要执行的函数
            // _Args&&... __args:函数的参数
    std::future<int> res = std::async(std::launch::async, Add, 11, 22);
    std::this_thread::sleep_for(std::chrono::seconds(1));

    std::cout << "-------------------------------\n";

        // get():获取异步执行的结果
    std::cout << res.get() << std::endl;

    return 0;
}

在这里插入图片描述

编译结果
在这里插入图片描述

代码流程图

主线程:
1. 创建延迟任务 res = async(deferred, Add) → 任务未启动
2. 休眠 1 秒 → 主线程空闲
3. 调用 res.get() → 触发任务执行
   - 执行 Add(11, 22) → 返回 33
4. 输出结果 → 结束

任务线程(无):
- 由于使用 deferred 策略,无独立线程创建。

2.2 异步执行std::packaged_task任务

#include <iostream>
#include <future>
#include <thread>


int Add(int num1, int num2){
    return num1 + num2;
}


int main(){
    // 1. 封装任务
    // std::packaged_task<int(int, int)> task(Add);
    auto task = std::make_shared<std::packaged_task<int(int, int)>>(Add);

    // 2. 获取任务包关联的future对象
    std::future<int> res = task->get_future();

    // 3. 执行任务
    std::thread thr([task](){ (*task)(11, 22); });

    // 4. 获取结果
    std::cout << res.get() << std::endl;
    
    return 0;
}

在这里插入图片描述

编译结果
在这里插入图片描述

代码运行图

主线程:
1. 创建 packaged_task(封装 Add)
2. 获取 future 对象
3. 启动子线程执行任务
4. 阻塞等待结果 → 输出 33

子线程:
1. 执行 (*task)(11, 22)
2. 计算结果 33 → 通过 future 传递结果

2.3 使用std::promise和std::future配合

std::promise提供了⼀种设置值的⽅式,它可以在设置之后通过相关联的std::future对象进⾏读取。换种
说法就是之前说过std::future可以读取⼀个异步函数的返回值了, 但是要等待就绪, ⽽std::promise就提供⼀种 ⽅式⼿动让 std::future就绪

#include <iostream>
#include <future>
#include <thread>
#include <memory>


int Add(int num1, int num2){
    return num1 + num2;
}


int main(){
    // 1. 在使用的时候,就是先实例化一个指定结果的 promise 对象
    std::promise<int> pro;

    // 2. 通过promise对象,获取关联的 future 对象
    std::future<int> res = pro.get_future();
    
    // 3. 在任意位置给promise设置数据,就可以通过关联的 future 获取到这个设置的数据了
    std::thread thr([&pro](){
        int sum = Add(11, 22);
        pro.set_value(sum);
    });
    
    std::cout << res.get() << std::endl;
    thr.join();

    return 0;
}

在这里插入图片描述

编译结果
在这里插入图片描述
代码运行图

主线程:
1. 创建 promise 和 future → pro 和 res
2. 启动子线程 thr → 执行 Add(11, 22)
3. 调用 res.get() → 阻塞等待结果
4. 子线程设置值 → res.get() 返回 33
5. 输出结果 → 结束

子线程:
1. 计算 11 + 22sum = 33
2. 调用 pro.set_value(33) → 唤醒主线程

👥总结

本篇博文对 【从零实现Json-Rpc框架】- 第三方库介绍 - fature篇 做了一个较为详细的介绍,不知道对你有没有帮助呢

觉得博主写得还不错的三连支持下吧!会继续努力的~

请添加图片描述


http://www.kler.cn/a/600596.html

相关文章:

  • vue2拦截器 拦截后端返回的数据,并判断是否需要登录
  • MCP协议生态重构AI开发范式:从工具碎片化到系统整合的革命性跨越
  • 【C++11】智能指针:std::shared_ptr
  • MySQL基础语法
  • 文字也能生成视频?【蓝耘实践】:通义万相2.1文生视频
  • cursor安装
  • 生成式媒介革命已至,搜索如何借力DeepSeek破局?
  • DeepSeek加持Excel,探索办公自动化的无限可能
  • Deepseek API+Python 测试用例一键生成与导出 V1.0.3
  • Julia语言的二进制与编码
  • 画秒杀系统流程图
  • 中级消防设施操作员(维保)考试的重点内容有哪些?
  • jeecgboot-vue3使用a-select placeholder不显示
  • 【AI神经网络】深度神经网络(DNN)技术解析:从原理到实践
  • 【动态规划】-- 第N个泰波拉契数
  • Redmi Note 11 T pro + 刷入 LinegaOs 22.1 记录 手机已经解锁bl.
  • 基于web的家政服务网站
  • 记一次线上程序宕机问题分析【写 GC 日志导致进程挂起】
  • 【Linux线程】——线程同步线程互斥
  • Doris通过时间字段,按照周分组统计的sql