C++20协程编程必知必会(co_yield返回值全解密)

第一章:C++20协程与co_yield概述

C++20 引入了原生协程支持,为异步编程提供了更简洁、高效的语法结构。协程是一种可暂停和恢复执行的函数,适用于生成器、异步任务和惰性求值等场景。`co_yield` 是协程中的核心关键字之一,用于将值传递给调用方并暂停当前协程的执行。

协程的基本特征

C++20 协程具有以下三个关键字作为语法标识:
  • co_await:用于等待一个可等待对象(awaiter)
  • co_yield:将值产出并挂起协程
  • co_return:结束协程并可返回最终结果
只要函数中包含上述任一关键字,即被视为协程。协程的返回类型必须满足协程接口(即定义 promise_type)。

使用 co_yield 实现生成器

下面是一个基于 std::generator(C++23 中引入,部分编译器在 C++20 模式下支持)的简单整数序列生成器示例:

#include <coroutine>
#include <iostream>

// 简化生成器实现示意(实际需自定义 promise)
struct Generator {
    struct promise_type {
        int current_value;
        std::suspend_always yield_value(int value) {
            current_value = value;
            return {};
        }
        std::suspend_always initial_suspend() { return {}; }
        std::suspend_always final_suspend() noexcept { return {}; }
        Generator get_return_object() { return Generator{this}; }
        void return_void() {}
        void unhandled_exception() {}
    };

    using handle_type = std::coroutine_handle<promise_type>;
    handle_type h_;

    explicit Generator(promise_type* p) : h_(handle_type::from_promise(*p)) {}

    int value() const { return h_.promise().current_value; }
    bool move_next() { 
        if (!h_.done()) h_.resume();
        return !h_.done(); 
    }
};

Generator generate_ints(int n) {
    for (int i = 0; i < n; ++i) {
        co_yield i; // 暂停并返回当前 i
    }
}
该代码中,co_yield i 将整数值 i 传递给调用方,并挂起协程,直到下一次调用 move_next() 恢复执行。

协程状态管理机制

协程的状态通过编译器生成的帧对象维护,包括局部变量、挂起点和 promise 对象。下表列出了关键组件的作用:
组件作用
promise_type定义协程行为逻辑,如初始/最终挂起、返回对象构造
coroutine_handle用于控制协程的生命周期和执行流程
yield_value()处理 co_yield 表达式的值传递逻辑

第二章:co_yield返回值的底层机制解析

2.1 协程框架中的awaiter与promise_type协作

在C++协程中,awaiter与promise_type通过标准化接口实现执行流的控制与结果传递。协程挂起时,运行时调用awaiter.await_ready()判断是否需暂停,并通过await_suspend注册恢复逻辑。
核心交互流程
  • promise_type由编译器注入协程体,管理最终结果与异常
  • awaiter来自co_await表达式的返回值,控制挂起点行为
  • await_suspend接收handle<promise_type>,用于后续恢复
struct TaskPromise {
    auto get_return_object() { return Task{this}; }
    auto initial_suspend() { return std::suspend_always{}; }
    auto final_suspend() noexcept { return std::suspend_always{}; }
    void unhandled_exception() { /* ... */ }
    void return_value(int v) { value = v; }
    int value;
};
上述代码定义了promise_type的基本结构,其中initial_suspend决定协程启动时是否立即挂起,return_value保存co_return的值。

2.2 co_yield表达式如何触发await_write操作

在C++20协程中,`co_yield`表达式用于暂停执行并返回一个值,其底层机制依赖于编译器生成的代码与用户定义的`promise_type`交互。
协程挂起流程
当执行到`co_yield value`时,编译器将其转换为:

promise.get_return_object().await_ready();
// 若需异步写入,返回false触发挂起
promise.await_suspend(handle);
若`await_ready()`返回`false`,则调用`await_suspend`,传入当前协程句柄,进而触发`await_write`类操作。
与IO系统的集成
常见实现中,`await_suspend`会注册完成回调或提交异步写请求:
  • 将协程句柄保存至IO任务队列
  • 触发底层write系统调用
  • 待数据写入完成,恢复协程执行
这一机制实现了非阻塞IO与协程的无缝衔接。

2.3 返回值类型自动推导与operator co_await重载

在现代C++协程中,返回值类型的自动推导极大简化了协程函数的定义。通过`auto`关键字,编译器可根据`promise_type`的定义自动推导出协程返回类型。
返回类型推导机制
当协程函数返回`auto`时,编译器会生成一个隐藏的返回对象,其类型由`std::experimental::suspend_always::promise_type`决定。例如:
auto async_func() {
    co_return 42;
}
该函数实际返回一个协程句柄包装类型,支持`co_await`操作。
operator co_await重载
用户可通过重载`operator co_await`自定义等待行为。该操作符返回一个awaiter对象,控制协程的暂停、恢复逻辑。
  • awaiter必须提供await_ready()
  • 定义await_suspend(handle)
  • 实现await_resume()
此机制为异步编程提供了高度灵活的扩展能力。

2.4 promise_type中return_value与yield_value的区别

在C++协程中,promise_type的return_value和yield_value控制着不同类型的值传递行为。
return_value 的调用时机
该方法用于处理协程通过 co_return 返回的最终值。它将值存储到promise对象中,供外部获取结果。
void return_value(T value) {
    result = value;
}
此函数通常不返回值,仅负责保存结果。
yield_value 的作用
当协程使用 co_yield 时,会调用 yield_value,允许生成器逐个产生值。
  • 可用于实现惰性序列生成
  • 每次调用后协程暂停,直到下一次恢复
两者核心区别在于:return_value标记协程结束,而yield_value实现中间值的逐步产出。

2.5 编译器如何将co_yield转换为状态机逻辑

C++20协程中,co_yield关键字并非直接暂停函数执行,而是触发编译器生成状态机代码,管理协程的挂起与恢复。
状态机转换过程
编译器将包含co_yield的函数重写为类,每个co_yield expr被替换为保存当前状态、设置返回值并调用awaiter.suspend_always()的逻辑。

task<int> counter() {
    for (int i = 0;; ++i)
        co_yield i;
}
上述代码被转换为包含状态字段(如state)、当前值(current_value)和恢复逻辑的有限状态机。每次co_yield i等价于: - 存储i到协程帧; - 将状态跳转编号存入控制块; - 返回promise.get_return_object()给调用者。
状态转移表
原状态事件动作新状态
S0co_yield v保存v,挂起S1
S1resume()清除挂起点S0

第三章:常见返回值类型的实践应用

3.1 使用int、bool等基本类型作为co_yield返回值

在C++20协程中,co_yield可用于暂停执行并返回一个值,其返回类型可直接为基本类型如int、bool等。这些类型轻量且无需复杂构造,适合高效传递简单数据。
基础用法示例
generator<int> count_up_to(int n) {
    for (int i = 1; i <= n; ++i)
        co_yield i;
}
上述代码定义了一个返回整数序列的协程。每次调用co_yield i时,将当前值传出并挂起,直到下一次迭代恢复。类型int被直接封装进协程状态。
支持的基本类型
  • int:常用于计数或状态码
  • bool:表示条件结果或开关状态
  • double:浮点计算结果传递
这些类型无需额外开销,编译器能高效处理其拷贝与生命周期,是协程通信的理想选择。

3.2 返回自定义对象并管理生命周期的正确方式

在 Go 语言中,返回自定义对象时应优先使用指针以避免值拷贝,并通过构造函数统一实例化逻辑。
构造函数与初始化
推荐使用工厂函数封装对象创建过程,确保初始化一致性:
type Resource struct {
    data string
    closed bool
}

func NewResource(data string) *Resource {
    return &Resource{
        data: data,
        closed: false,
    }
}
该模式确保对象始终处于有效状态,避免零值误用。
生命周期管理
通过接口定义资源释放行为,显式控制生命周期:
  • 实现 Close() 方法标记资源状态
  • 结合 defer 确保及时释放
func (r *Resource) Close() {
    if !r.closed {
        r.closed = true
        // 释放相关系统资源
    }
}
调用者需负责调用 Close(),实现确定性的资源回收。

3.3 引用类型作为返回值的风险与规避策略

在Go语言中,将引用类型(如切片、map、指针)作为函数返回值时,可能暴露内部状态,导致调用者意外修改原始数据。
常见风险场景
func GetData() map[string]int {
    data := map[string]int{"a": 1, "b": 2}
    return data // 返回原始map引用
}
上述代码返回的是map的引用,调用者可直接修改原数据,破坏封装性。
规避策略
  • 返回副本而非引用:对map和切片进行深拷贝
  • 使用不可变结构:通过接口限制写操作
  • 延迟初始化:结合sync.Once保护并发访问
安全返回示例
func SafeGetData() map[string]int {
    data := map[string]int{"a": 1, "b": 2}
    copy := make(map[string]int)
    for k, v := range data {
        copy[k] = v
    }
    return copy // 返回副本
}
该方式通过手动复制map,避免外部修改原始数据,保障数据完整性。

第四章:高级场景下的返回值处理技巧

4.1 支持移动语义的对象返回优化实战

在现代C++开发中,通过移动语义优化对象返回能显著减少不必要的拷贝开销。当函数返回大型对象时,编译器若无法执行RVO(Return Value Optimization),则会尝试调用移动构造函数。
移动构造的触发条件
必须确保返回对象是临时值或使用std::move显式转移所有权。例如:

class LargeBuffer {
public:
    std::vector<int> data;
    LargeBuffer(LargeBuffer&& other) noexcept : data(std::move(other.data)) {}
};

LargeBuffer createBuffer() {
    LargeBuffer buf;
    buf.data.resize(10000);
    return buf; // 触发移动构造,避免深拷贝
}
上述代码中,return buf;将匹配移动构造函数,std::move使data内部指针转移,时间复杂度从O(n)降至O(1)。
性能对比
  • 拷贝返回:深度复制所有元素,开销大
  • 移动返回:仅转移资源指针,高效且安全

4.2 暂停点间数据传递与惰性求值模式设计

在复杂的数据处理流程中,暂停点间的数据传递需兼顾状态保持与资源效率。通过引入惰性求值机制,可延迟计算直至真正需要结果,减少冗余执行。
惰性求值的实现结构
  • 封装数据流节点为可暂停的计算单元
  • 使用闭包保存上下文环境
  • 通过信号量控制执行时机
代码示例:Go 中的惰性求值链

type LazyValue struct {
    evalFunc func() interface{}
    cached   interface{}
    evaluated bool
}

func (l *LazyValue) Get() interface{} {
    if !l.evaluated {
        l.cached = l.evalFunc()
        l.evaluated = true
    }
    return l.cached
}
上述结构通过evalFunc延迟实际计算,首次调用Get时触发并缓存结果,后续访问直接返回,有效支持暂停点恢复时的数据一致性。

4.3 处理异常时的返回值安全机制

在异常处理过程中,确保返回值的安全性是防止资源泄漏和状态不一致的关键。函数即使在出错时也应提供明确的返回语义。
错误码与零值分离设计
避免将错误状态隐式编码为返回值的一部分,推荐使用多返回值模式显式分离结果与错误:

func divide(a, b float64) (result float64, err error) {
    if b == 0 {
        return 0, fmt.Errorf("division by zero")
    }
    return a / b, nil
}
该函数始终返回两个值:计算结果和错误标识。调用方必须检查 err 才能安全使用 result,从而杜绝误用无效数据。
延迟恢复与状态回滚
通过 defer 配合 recover 可实现安全的异常捕获,同时保障返回值一致性:
  • 延迟函数可用于清理资源
  • panic 被捕获后可转换为标准错误返回
  • 避免因异常导致调用栈断裂而返回未定义值

4.4 实现生成器模式中多值连续产出的最佳实践

在生成器模式中实现多值连续产出,关键在于控制状态的保持与按需计算。使用惰性求值机制可有效提升性能,避免一次性加载大量数据。
使用通道与协程实现流式产出
在 Go 语言中,通过 goroutine 与 channel 可以优雅地实现生成器:
func numberGenerator() <-chan int {
    ch := make(chan int)
    go func() {
        defer close(ch)
        for i := 1; i <= 5; i++ {
            ch <- i // 按需发送值
        }
    }()
    return ch
}
该实现通过无缓冲通道实现推送式流,每次产出一个值即暂停,直到消费者接收,确保内存高效。
最佳实践清单
  • 始终在 goroutine 中执行生成逻辑,避免阻塞主流程
  • 使用 defer close(channel) 防止资源泄漏
  • 优先采用无缓冲通道以实现同步通信

第五章:总结与未来展望

云原生架构的持续演进
现代企业正加速向云原生转型,Kubernetes 已成为容器编排的事实标准。以下是一个典型的 Helm Chart values.yaml 配置片段,用于在生产环境中部署高可用微服务:
replicaCount: 3
image:
  repository: myapp
  tag: v1.4.0
  pullPolicy: IfNotPresent
resources:
  limits:
    cpu: "500m"
    memory: "512Mi"
该配置确保了资源隔离与弹性伸缩基础,结合 Horizontal Pod Autoscaler 可实现基于 CPU 使用率的自动扩缩容。
AI 驱动的运维自动化
AIOps 正在重构传统监控体系。某金融客户通过 Prometheus + Grafana + ML 模型预测磁盘容量趋势,提前7天预警潜在风险。其核心算法输入特征包括:
  • 历史写入速率(日均增长量)
  • 业务周期性波动(如月末报表生成)
  • 备份任务执行频率
  • 冷热数据迁移策略生效时间
边缘计算与 5G 的融合场景
在智能制造领域,某汽车装配线部署了边缘节点集群,实现视觉质检延迟低于50ms。下表展示了边缘与中心云的数据处理分工:
处理层级数据类型响应延迟要求处理技术栈
边缘节点实时视频流<100msTensorRT + ONNX Runtime
区域云聚合分析结果<5sSpark + Kafka
Unity代码混淆实战:Obfuscator Pro配置与JSON、协程、动画事件避坑指南 代码混淆是软件安全领域的一项基础技术,其核心原理是通过重命名、控制流混淆和字符串加密等手段,将源代码转换为功能等效但难以逆向分析的形式,从而保护核心知识产权。这项技术在商业软件、游戏开发中具有重要价值,能有效防止反编译和算法窃取。在Unity游戏开发的应用场景中,混淆是发布前的关键安全步骤,但直接应用可能破坏依赖固定名称的引擎功能。本文聚焦于Unity Asset Store中广受认可的Obfuscator Pro工具,深入解析其分层保护策略,并针对【JSON序列化】和【动画事件】这两个高频热词场景,提供详 阅读详情

相关推荐

解密M350 RTK飞控日志:从加密文件到三维轨迹可视化的全流程

本文详细解析了M350 RTK飞控日志的解密与三维轨迹可视化全流程,涵盖从加密文件提取、关键飞行参数分析到坐标转换与三维可视化的实用技巧。特别针对大疆无人机飞控数据,提供了异常检测与工程化应用建议,帮助用户高效处理和分析飞行数据。

weixin_34111790的博客 360

突破 C++ 性能与架构的终极迷宫:从异步地狱到 C++20 无栈协程(Coroutines)

C++20协程:非阻塞异步I/O的革命性解决方案 摘要: C++20引入的协程技术彻底改变了高并发编程范式,允许开发者用同步代码的直观性实现高性能非阻塞I/O操作。相较于传统多线程模型(资源消耗大)和回调模型(逻辑碎片化),无栈协程通过状态机机制在挂起时保存执行上下文,恢复时继续执行,实现零阻塞的高效并发。其核心架构基于Promise(控制协程生命周期)、Awaiter(管理挂起/恢复逻辑)和协程句柄(操作底层状态)。实战案例显示,协程能优雅重构传统阻塞式代码,但需警惕生命周期管理(如悬挂引用)等工程陷阱。

greenspan的专栏 415

Python异步并发实战:用asyncio提升单机吞吐与响应性能

Python的异步编程本质是解决I/O密集型场景下的资源利用率瓶颈——在GIL限制下,传统同步阻塞调用导致线程空转、CPU闲置;而asyncio通过事件循环与协程协作调度,实现单线程内万级并发,将‘等待’转化为‘并行处理’。其技术价值在于不增加硬件成本的前提下显著提升QPS、降低P95延迟、优化内存与文件描述符使用率。典型应用场景包括高并发API网关、实时数据聚合服务、短链跳转系统及微服务间异步调用。本文聚焦asyncio在真实业务中的落地路径,涵盖事件循环生命周期管理、asyncpg连接池调优、httpx

weixin_30591551的博客 465

llama.cpp本地大模型部署:从编译到生产级API全链路指南

大模型本地推理是AI工程化落地的关键环节,其核心在于轻量、可控、可嵌入的推理引擎。llama.cpp作为专为CPU/GPU优化的纯C/C++推理框架,通过GGUF模型格式、细粒度CUDA架构支持与确定性参数控制,突破了PyTorch等通用框架在资源效率与硬件适配上的瓶颈。它不仅支撑Q4_K_M等量化模型在消费级显卡(如RTX 3060/4090)上实现低延迟高吞吐推理,更提供稳定C API与llama-server微服务能力,成为RAG、Agent、ComfyUI插件及边缘部署的事实基座。本文聚焦Windo

weixin_30448603的博客 501

Ollama本地大模型部署与国密SM4加密通信实战指南

本地大模型部署是当前AI应用开发的热点方向,它通过在用户本地设备上运行模型,实现了数据不出域、隐私安全可控的核心优势。其技术原理主要基于轻量化模型压缩与高效推理引擎,能够在消费级硬件上提供可用的AI能力。从技术价值看,本地部署解决了云端服务的延迟、成本和数据隐私问题,尤其适合对数据安全有严格要求的场景。在应用层面,本地大模型常被用于智能助手、文档分析和代码生成等任务。针对模型部署中的通信安全问题,国密算法提供了符合国内合规要求的加密解决方案。本文聚焦于使用Ollama框架部署LFM2.5-1.2B-Thin

weixin_30411819的博客 399

钉钉Java面经及参考答案

TCP 三次握手建立连接的核心目标是双向确认双方发送、接收能力,同步通信序列号,协商初始窗口大小,防止历史过期连接报文干扰新连接。第一次握手,客户端主动向服务端发送 SYN 报文,携带客户端随机生成的初始序列号 ISN,客户端状态变更为 SYN_SENT,目的是告知服务端客户端具备发送数据的能力。第二次握手,服务端收到 SYN 报文后,回复 SYN+ACK 报文,其中 ACK 确认号为客户端 ISN+1,同时携带服务端自身随机初始序列号,服务端进入 SYN_RCVD 状态,代表服务端确认收到客户端报文,且自

大模型大数据攻城狮的专栏 238

Tink Python Streaming AEAD 实战:用 AES256_CTR_HMAC 流式加密解密大文件

Tink 是 Google 开源的多语言、跨平台密码学库,而 Streaming AEAD 是其针对"大文件流式加解密"场景提供的核心原语。本文以仓库中的官方示例 [python/examples/streaming_aead/README.md](https://link.gitcode.com/i/1c2a574b33cc2613fe48ae87cf89792e) 为主体,完整讲解如何用 Ti

gitblog_01099的博客 636

产业园区如何高效对接企业技术需求与高校科研成果?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

Unity HLS加密播放实战:动态密钥分发与多端解密架构

HLS(HTTP Live Streaming)是一种广泛使用的自适应流媒体协议,其AES-128加密机制本质在于密钥分发控制,而非单纯文件加锁。理解HLS加密原理需明确:.m3u8中明文URI指向的crypt.key若静态暴露,将导致整套加密形同虚设;真正安全依赖密钥动态生成、设备绑定与短时失效策略。在Unity引擎中实现安全播放,需突破VideoPlayer原生限制,构建网络层拦截、C#或NDK侧流式AES-128-CBC解密、以及AVPro Video外部纹理渲染的三层解耦架构。该方案直面Pico4头

weixin_34332905的博客 376

TensorRT-LLM环境配置避坑指南:从安装到实战

本文是一份详尽的TensorRT-LLM环境配置避坑指南。文章重点解析了从Python、CUDA、PyTorch版本选择,到解决mpi4py安装这一核心难题的完整流程,并提供了经过验证的稳定版本组合与实战排错方案,帮助开发者高效部署大语言模型推理优化环境。

a0b1c2d3的专栏 984

VSAN 虚拟机丢失排查与恢复完整方案

VSAN虚拟机(含vCenter)显示无效 检查存储状态:登录ESXi Host Client,确认VSAN存储是否挂载。 若未挂载,通过SSH执行 手动挂载。 验证文件存在:检查虚拟机文件是否完整。 解除文件锁定:删除残留的 .lck 文件 手动注册虚拟机:强制注册虚拟机配置文件。 检查VSAN健康:验证集群节点在线、磁盘组状态正常,并测试节点间网络。 修复元数据:针对损坏对象,谨慎执行修复。 终极恢复:若数据丢失,从备份还原或联系VMware支持,提交日志

sido777的博客 2680

Sphinx C++ 域多声明查找机制详解:基于 multi-decl-lookup 测试用例的源码级剖析

> 导读:本文以 Sphinx 仓库中 C++ 域(`cpp` domain)的专项测试根文件 `multi-decl-lookup.rst` 为核心,深入剖析其背后的"同一指令内多签名声明"解析机制。你将掌握如何在同一 `cpp:function` / `cpp:class` 指令中声明重载函数、函数模板与类模板,理解这些声明为何能互相可见(供参数与模板参数的类型引用解析),以及 Sphinx

gitblog_00925的博客 1133

使用protege推理小例子---关系链

使用protege推理小例子---关系链关系链推理 SubPropertityChain在Protege中使用关系链推理1、创建Person类2、创建对象关系3、添加实例4、进行推理5、推理结果 关系链推理 SubPropertityChain 关系链简单的说就是将多个关系表达式串联起来,如下图 1-1 图1-1 小明的父亲是大明,大明的父亲是老明。这就是一个由两组关系连接的关系链,根据关系链可以推理出,小明和老明之间的关系是爷孙关系。 在Protege中使用关系链推理 1、创建Person类 在Entit

weixin_45237780的博客 4459

Boost.Asio SSL/TLS 实战:`ssl::stream<>` 全风格通用原理、握手流程与并发安全配置

在异步 C++ 网络编程中启用 TLS 加密,Boost.Asio 给出了一个贯穿所有异步风格(C++20 协程、回调、stackful coroutine、经典 `io_service`)的统一答案:`ssl::stream<>`。本文以 [ssl.md](https://pre-link.gitcode.com/i/be8d82239b35a9f08f7a9913f54f144a) 为核心骨架

gitblog_00184的博客 397

手把手教你用SlowFast训练自定义手势识别数据集(附FFmpeg抽帧技巧)

本文提供了一份基于SlowFast架构训练自定义手势识别数据集的完整实战指南。文章重点剖析了数据准备的核心挑战,详细讲解了利用FFmpeg进行高、低帧率抽帧的技巧,并介绍了构建半自动标注流水线、生成符合SlowFast要求的AVA格式数据集文件的具体方法。最后,针对手势识别场景,给出了关键的模型训练配置与调优建议,帮助开发者高效完成从数据到模型的全流程。

s1t2u3的博客 909

台球 PCOL:极致物理还原的网页斯诺克引擎(附源码深度解析)

*完整源码地址**:[https://github.com/billiards/pcol-core](https://github.com/billiards/pcol-core)(包含详细文档与示例)通过这个项目,我们不仅创建了一个游戏,更构建了一个**可扩展的物理引擎框架**,为网页端复杂物理模拟开辟了新的可能性。**在线体验**:[https://pcol.billiards](https://pcol.billiards)(支持移动端触控操作)clone.velocity.x *= -0.92;

Loving_enjoy的博客 2797

C++在AI框架中的高效应用与优化实践

C++作为系统级编程语言,在人工智能领域展现出独特的性能优势。其核心价值在于底层硬件操作能力和高效内存管理,特别适合实时推理、嵌入式部署等高性能场景。通过TensorFlow C++ API和PyTorch LibTorch等工具,开发者可以实现从Python训练到C++部署的完整流程。关键技术包括SIMD指令优化、内存池预分配、多线程无锁队列等工程实践,在工业级应用中可实现数倍的性能提升。这些优化手段在自动驾驶、高频交易、计算机视觉等对延迟敏感的场景中尤为重要,同时也为模型加密、跨平台部署等需求提供了可靠

weixin_30520015的博客 334

2026年职业院校技能大赛中职移动应用与开发—数字生活APP原型设计参考答案(含素材)

本模块以产品原型为目标,考查参赛选手熟练收集、分析和归纳客户需求,清晰梳理业务流程,熟练使用UI设计软件进行产品UI/UE设计,掌握正确的UI配色方案,设计出符合业务逻辑的人体工学移动App 原型优秀作品。

我是网络安全兼技能大赛工程师,专注网络安全技术学习与技能大赛实战!持续分享最新的技术文章,帮你少走弯路,一起在技术赛道上进步~ 568

Lua引擎框架设计与优化实践指南

Lua作为轻量级脚本语言,凭借其精简设计和高性能特性,在嵌入式系统和游戏开发中广泛应用。其核心原理基于虚拟机机制,通过Lua C API实现与宿主语言的高效交互,为系统提供灵活的脚本扩展能力。在性能优化方面,Lua表的预分配、局部变量使用和内存管理策略能显著提升执行效率。热更新机制和沙箱安全模型是Lua引擎框架的关键技术价值,支持游戏逻辑动态更新和嵌入式设备安全隔离。本文以LuaJIT和标准Lua对比为切入点,深入解析自研框架中的内存优化、定时器管理等实践方案,为高并发场景和资源受限环境提供解决方案。

weixin_30788239的博客 343

手把手教你学Simulink——四开关 Buck‑Boost(FSBB)变换器的无缝模式切换仿真

本文详细介绍了四开关Buck-Boost(FSBB)变换器的Simulink仿真方法,重点解决模式切换时的直通风险和输出电压波动问题。通过统一电压PI控制、迟滞比较模式仲裁(Buck/Boost/Pass-Through)和200ns死区设计,实现了Vin从26V到22V变化时Vout稳定在12V±0.15V。关键步骤包括:搭建功率级电路、Stateflow模式判断、PI控制器输出占空比映射(Buck模式D≈Vo/Vin,Boost模式D≈1-Vo/Vin),以及带死区的PWM信号分配。仿真验证了切换过程中

MHD0815的博客 116

WPF实战案例 | C# WPF实现大学选课系统

WPF实战案例_C# WPF实现大学选课系统, C# WPF实现大学选课系统,大作业,毕业设计,该系统实现多身份登录、修改密码、课程的管理,个人信息的管理等功能。这个源码让你快速搭建自己的应用程序,注释完整,代码规范,各种风格都有,代码上手简单,代码独立,可以直接用程序打开,运行使用。也可直接点击EXE运行程序。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 4624

ESP32-P4边缘跑LLM:从0.61到4.31 tok/s实战优化

轻量级大语言模型(LLM)在资源受限嵌入式设备上的本地推理,正成为边缘AI落地的关键路径。其核心原理在于突破传统‘堆算力’范式,转向内存带宽、功耗、延迟与精度的协同优化。技术价值体现在无需云端依赖、全链路数据不出芯片、超低功耗下实现可执行语义理解。典型应用场景包括工业传感器异常判断、农业墒情自然语言解释、儿童教育硬件离线问答等。本文聚焦ESP32-P4平台,结合RISC-V架构特性与Mistral-7B模型GQA结构,详解如何通过定制量化(Q4_K_M_16)、KV cache bank化管理、PSRAM内

weixin_33922672的博客 427

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

深入解析GDScript反编译工具:从PCK/APK中完整恢复Godot项目的实战指南

**GDScript反编译**是Godot游戏逆向工程的核心技术,能够从已发布的PCK、APK或EXE文件中完整恢复原始项目资源。这款开源工具为开发者提供了强大的项目恢复能力,无论是学习优秀游戏实现、进行安全审计,还是从丢失源码的项目中恢复资源,都能提供专业的技术支持。 ## 🎯 项目概述与技术背景 在Godot游戏开发生态中,项目发布通常会将资源打包成PCK文件或嵌入到可执行文件中。这种打

gitblog_00088的博客 516

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Python函数式编程实战:生成器驱动的数据流水线

函数式编程是一种以数据流为核心、强调无状态变换的编程范式,其核心原理在于将计算建模为‘输入→变换→输出’的纯函数链式调用。在Python中,它并非追求Haskell式的严格纯函数,而是通过生成器、map/filter/reduce、高阶函数等轻量机制,实现内存友好、可组合、易测试的数据处理能力。技术价值体现在显著降低中间状态管理成本、规避大文件OOM风险、提升流水线可维护性;典型应用场景包括日志分析、ETL清洗、API响应流处理及实时指标聚合。本文聚焦Python特有的函数式实践路径,深入解析生成器惰性求值

dianxi0949的博客 464

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

mruby 虚拟机内部实现解析:从寄存器执行模型到方法分发与 Fiber 切换

mruby 是一款面向嵌入式与受限环境的轻量级 Ruby 实现,其虚拟机(VM)是整个运行时的核心。本文以仓库中的 [虚拟机内部文档](https://link.gitcode.com/i/65cf7fcc3ae2d2640b5c9c19fccf5249) 为主线,结合 [src/vm.c](https://link.gitcode.com/i/e07af5a097d0ddded7eb10b995

gitblog_01037的博客 900

基于FastAPI与本地AI模型构建隐私优先的语音日记应用

语音识别与自然语言处理技术正深刻改变人机交互方式,其核心原理在于将音频信号转化为文本,并利用大语言模型理解语义。这项技术的价值在于能实现更自然、高效的信息输入与智能处理,尤其适用于笔记、创作、复盘等需要快速记录与整理的场景。本文聚焦于构建一个隐私优先的AI语音日记应用,通过集成Whisper进行本地语音转文本,并利用Llama.cpp等开源大语言模型在本地进行内容分析与摘要生成,确保用户数据全程私密。项目采用FastAPI构建后端服务,结合数据加密技术,为开发者提供了一个融合全栈开发、AI集成与隐私安全实践

cqwmy840702的博客 366
上一篇: C++构造函数调用顺序陷阱大盘点(90%程序员都踩过的坑)
下一篇: 类成员初始化顺序必须遵循的3条铁律,违反一条就可能崩溃
quickcode
博客等级 码龄19年 146粉丝 1996原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值