C++并发之协程实例(二)(计算斐波那契序列)

2024-06-21 16:44

本文主要是介绍C++并发之协程实例(二)(计算斐波那契序列),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 1 协程
  • 2 实例-计算斐波那契序列
    • 2.1 斐波那契序列
    • 2.2 代码
  • 3 运行

1 协程

  协程(Coroutines)是一个可以挂起执行以便稍后恢复的函数。协程是无堆栈的:它们通过返回到调用方来暂停执行,并且恢复执行所需的数据与堆栈分开存储。这允许异步执行的顺序代码(例如,在没有显式回调的情况下处理非阻塞I/O),还支持惰性计算无限序列上的算法和其他用途。
协程类图如下:
协程类

2 实例-计算斐波那契序列

2.1 斐波那契序列

斐波那契数列是一位意大利的数学家,他闲着没事去研究兔子繁殖的过程,研究着就发现,可以写成这么一个序列:1,1,2,3,5,8,13,21… 也就是每个数等于它前两个数之和。那么给你第 n 个数,问 F (n) 是多少。
用数学公式表示很简单: f(n) = f(n-1) + f(n-2)
下面的例子使用协程来计算斐波那契序列

2.2 代码

#include <coroutine>
#include <cstdint>
#include <exception>
#include <iostream>template <typename T>
struct Generator
{struct promise_type;using handle_type = std::coroutine_handle<promise_type>;struct promise_type{T value_;std::exception_ptr exception_;Generator get_return_object(){return Generator(handle_type::from_promise(*this));}std::suspend_always initial_suspend() { return {}; }std::suspend_always final_suspend() noexcept { return {}; }void unhandled_exception() { exception_ = std::current_exception(); }template<std::convertible_to<T> From>std::suspend_always yield_value(From&& from)//设置完值后挂起协程{value_ = std::forward<From>(from);return {};}void return_void() {}};handle_type h_;Generator(handle_type h) : h_(h) {}~Generator() { h_.destroy(); }explicit operator bool(){fill();return !h_.done();}T operator()(){fill();full_ = false;return std::move(h_.promise().value_);}
private:bool full_ = false;void fill(){if(!full_){h_();//if(h_.promise().exception_)std::rethrow_exception(h_.promise().exception_);full_ = true;}}
};Generator<std::uint64_t>
fibonacci_sequence(unsigned n)//斐波那契序列
{if(n == 0)co_return;//计算结束 if(n > 94)throw std::runtime_error("太大斐波那契序列,元素将会溢出");co_yield 0;//挂起协程if(n == 1)co_return;//计算结束co_yield 1;if(n == 2)co_return;std::uint64_t a = 0;std::uint64_t b = 1;for(unsigned i = 2; i < n; ++i){std::uint64_t s = a + b;co_yield s;//挂起协程a = b;b = s;}//计算结束
}int main(int argc, char *argv[])
{int n = 10;if(argc > 1)n = std::stoul(argv[1]);try{auto gen = fibonacci_sequence(n);for(int j = 0; gen; ++j)//调用operator bool()判断是gen是否计算结束std::cout << "fib(" << j << ")=" << gen() << std::endl;//调用T operator()()返回计算j对应的斐波那契序列值}catch(const std::exception& e){std::cerr << "异常: " << e.what() << std::endl;}catch(...){std::cerr << "未知异常\n";}return 0;
}

3 运行

$./example2 0
$./example2 0 1
fib(0)=0
$./example2 0 4
fib(0)=0
fib(1)=1
fib(2)=1
fib(3)=2
$./example2 0 10
fib(0)=0
fib(1)=1
fib(2)=1
fib(3)=2
fib(4)=3
fib(5)=5
fib(6)=8
fib(7)=13
fib(8)=21
fib(9)=34
$./example2 95
异常: 太大斐波那契序列,元素将会溢出

这篇关于C++并发之协程实例(二)(计算斐波那契序列)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1081763

相关文章

Python的Darts库实现时间序列预测

《Python的Darts库实现时间序列预测》Darts一个集统计、机器学习与深度学习模型于一体的Python时间序列预测库,本文主要介绍了Python的Darts库实现时间序列预测,感兴趣的可以了解... 目录目录一、什么是 Darts?二、安装与基本配置安装 Darts导入基础模块三、时间序列数据结构与

C++右移运算符的一个小坑及解决

《C++右移运算符的一个小坑及解决》文章指出右移运算符处理负数时左侧补1导致死循环,与除法行为不同,强调需注意补码机制以正确统计二进制1的个数... 目录我遇到了这么一个www.chinasem.cn函数由此可以看到也很好理解总结我遇到了这么一个函数template<typename T>unsigned

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

Python实现精确小数计算的完全指南

《Python实现精确小数计算的完全指南》在金融计算、科学实验和工程领域,浮点数精度问题一直是开发者面临的重大挑战,本文将深入解析Python精确小数计算技术体系,感兴趣的小伙伴可以了解一下... 目录引言:小数精度问题的核心挑战一、浮点数精度问题分析1.1 浮点数精度陷阱1.2 浮点数误差来源二、基础解决

Web服务器-Nginx-高并发问题

《Web服务器-Nginx-高并发问题》Nginx通过事件驱动、I/O多路复用和异步非阻塞技术高效处理高并发,结合动静分离和限流策略,提升性能与稳定性... 目录前言一、架构1. 原生多进程架构2. 事件驱动模型3. IO多路复用4. 异步非阻塞 I/O5. Nginx高并发配置实战二、动静分离1. 职责2

C# LiteDB处理时间序列数据的高性能解决方案

《C#LiteDB处理时间序列数据的高性能解决方案》LiteDB作为.NET生态下的轻量级嵌入式NoSQL数据库,一直是时间序列处理的优选方案,本文将为大家大家简单介绍一下LiteDB处理时间序列数... 目录为什么选择LiteDB处理时间序列数据第一章:LiteDB时间序列数据模型设计1.1 核心设计原则

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

MySQL的配置文件详解及实例代码

《MySQL的配置文件详解及实例代码》MySQL的配置文件是服务器运行的重要组成部分,用于设置服务器操作的各种参数,下面:本文主要介绍MySQL配置文件的相关资料,文中通过代码介绍的非常详细,需要... 目录前言一、配置文件结构1.[mysqld]2.[client]3.[mysql]4.[mysqldum

Python文本相似度计算的方法大全

《Python文本相似度计算的方法大全》文本相似度是指两个文本在内容、结构或语义上的相近程度,通常用0到1之间的数值表示,0表示完全不同,1表示完全相同,本文将深入解析多种文本相似度计算方法,帮助您选... 目录前言什么是文本相似度?1. Levenshtein 距离(编辑距离)核心公式实现示例2. Jac