rust异步编程

简化版本 Future

// wake 函数 reactor发现状态是ready 通知executor 函数
trait SimpleFuture {
    type Output;
    fn poll(&mut self, wake: fn()) -> Poll<Self::Output>;
    // fn poll(&mut self, wake: u32) -> Poll<Self::Output>;
}

enum Poll<T> {
    Ready(T),
    Pending,
}
future 返回的是Poll枚举 , 状态有Ready ,pending 状态
executor 调用 Future 任务,Ready 执行完成, pending 阻塞 执行其他任务
reactor 检查任务是否变成 ready

在这里插入图片描述

  • simpleFuture 是一个trait, 属于struct MySleep
use std::thread;
use std::time::Duration;

trait SimpleFuture {
    type Output;
    // fn poll(&mut self, wake: fn()) -> Poll<Self::Output>;
    fn poll(&mut self, wake: u32) -> Poll<Self::Output>;
}

enum Poll<T> {
    Ready(T),
    Pending,
}

// 自定义循环技术
struct MySleeper {
    polls: u64,
    wake: u32, // 简化使用整数 替换函数
}

impl MySleeper {
    fn new(wake: u32) -> Self {
        MySleeper {
            polls: 0,
            wake: wake,
        }
    }
}

static mut FINISHED: bool = false;

impl SimpleFuture for MySleeper {
    type Output = ();
    fn poll(&mut self, wake: u32) -> Poll<Self::Output> {
        // 简化编程 使用unsafe 使用外部的变量
        unsafe {
            if FINISHED {
                Poll::Ready(())
            } else {
                self.wake = wake;
                self.polls += 1;
                println!("polls = {}", self.polls);
                Poll::Pending
            }
        }
    }
}

// 定义自定义Reactor
struct MyReactor {
    wake: u32,
    // 通知exector
    handle: Option<thread::JoinHandle<()>>, // 线程句柄
}

impl MyReactor {
    fn new() -> Self {
        MyReactor {
            wake: 0,
            handle: None,
        }
    }
    // 知道哪个wake 通知具体函数
    fn add_wake(&mut self, wake: u32) {
        self.wake = wake;
    }

    // check status
    fn check_status(&mut self) {
        if self.handle.is_none() {
            let wake = self.wake;
            // 模拟 通过死循环进行监控状态
            let handle = thread::spawn(|| loop {
                thread::sleep(Duration::from_secs(5));
                unsafe {
                    //模拟future就绪,然后调用wake
                    FINISHED = true;
                }
            });
            self.handle = Some(handle);
        }
    }
}

struct MyExecutor;

impl MyExecutor {
    fn block_on<F: SimpleFuture>(mut myfuture: F, wake: u32) {
        //阻塞执行future
        loop {
            match myfuture.poll(wake) {
                Poll::Ready(_) => {
                    println!("my future is ok");
                    break;
                }
                Poll::Pending => unsafe {
                    while !FINISHED {
                        // 循环 每隔一秒钟检测一下
                        thread::sleep(Duration::from_secs(1));
                    }
                }
            }
        }
    }
}

fn main() {
    let mut reactor = MyReactor::new();
    let sleeper = MySleeper::new(5);
    let wake = sleeper.wake;
    reactor.add_wake(wake);
    reactor.check_status();
    MyExecutor::block_on(sleeper, wake);
}

在简化版本的Future 对象中 有定义MyReactor, 和 MyExecutor, MyReactor wake 函数进行标记后调用自定义的check_staus 模拟Future的就绪,调用wake 函数通知, 在MyExector 的block_on 函数中 通过wake函数匹配状态 判读任务是否已经Ready

理解Future的模型

运行时状态的框架: async-std, futures 中已经实现executor不需要自己在实现。

  • 异步编程中,rust的编程语言中只给我们提供trait Future, async-std, tokio,futures 等异步编程库 对其进行扩展,并且提供相对应的函数
 async fn hello() {
     println!("hello");
 }
等价于下面函数
fn hello() -> impl Future<Output=()> {
    async {
        println!("hello");
    }
}


rust 标准库中 Future如下:

 pub trait Future {
     type Output;
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
 }
// Pin 可以创建不可移动Future,通过不可移动对象在他们字段中存储指针
struct MyFut {
	a: i32,
	ptr: *const i32, // 指针指向字段a 所在的内存首地址
}

async/awit 使用

  • 在闭包中使用async
use std::future::Future;

fn my_function() -> impl Future<Output  = u8> {
	let closure = async |x: u8| {
		x
	};
	
	closure(5)
}
闭包在稳定版本还不支持,后续的版本中会支持 异步闭包
##### async lifetime 

```rust
这个函数的生命周期
// fn foo_expand(x: &'a u8) -> impl Future<Output = u8> + 'a {
//     async {
//         *x
//     }
// }
async fn foo(x: & u8) -> u8 {
    *x
}
// async 函数返回一个Future的对象
 fn good() -> impl Future<Output = u8>{
 // 异步代码块中,定义 变量后 调用foo_expand async 函数后进行await
     async {
     // x 修饰后 x 的生命周期有多长 就有多长
        let x = 5;
        foo_expand(&x).await
   }
}
<think>好的,用户想了解Rust异步编程的学习和理解。首先,我需要回忆Rust异步编程的基本概念和核心机制。Rust异步编程主要围绕async/await语法、Future trait、执行器(Executor)、反应器(Reactor)等部分展开。用户可能已经有一定的同步编程经验,现在想转向异步以提高性能,特别是在处理高并发、I/O密集型任务时。 接下来,用户可能的疑问点包括:为什么Rust选择基于生成器的异步模型?Future在Rust中是如何工作的?async/await背后的机制是什么?执行器和反应器各自扮演什么角色?还有常见的运行时如tokio和async-std的区别和使用场景。 需要分步骤解释,从基本概念入手,逐步深入。首先介绍异步编程解决的问题,然后讲解Future trait,接着是async/await语法糖,再讨论执行器和反应器如何协作,最后提到生态中的运行时库。同时要提醒常见的陷阱,比如阻塞操作在异步任务中的影响,以及Pin和Unpin的作用。 可能用户的实际需求是在项目中高效处理大量网络请求或文件I/O,所以需要强调Rust异步在性能上的优势,比如零成本抽象和避免全局运行时开销。此外,应该提供简单的代码示例,展示如何定义异步函数和使用.await,以及选择运行时库的基本方法。 还要注意用户的潜在问题,比如错误处理、任务取消、跨线程调度等高级话题,但初次学习可能不需要深入这些细节,点到为止即可。最后,总结学习路径,推荐官方文档和社区资源,帮助用户继续深入学习。</think>以下是Rust异步编程的核心概念分步解析(建议结合代码实践理解): 一、同步与异步的本质区别 同步模型:线程阻塞等待I/O完成 → 高并发时线程切换开销大 异步模型:单线程内多任务交替执行 → 通过状态机实现非阻塞 二、Rust异步核心三要素 1. Future trait(异步计算抽象) ```rust pub trait Future { type Output; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>; } ``` - 每个async块编译后生成实现Future的状态机 - poll方法驱动状态机推进(非递归调用) 2. 执行器(Executor) - 线程池调度管理Future任务 - 典型实现:tokio::runtime、async-std::task 3. 反应器(Reactor) - 事件循环监控I/O就绪状态 - 通过epoll/kqueue/IOCP等系统调用实现 三、async/await工作流程 1. 定义异步函数 ```rust async fn fetch_data() -> Result<String, io::Error> { // 模拟异步操作 tokio::time::sleep(Duration::from_secs(1)).await; Ok("Data".to_owned()) } ``` 2. 执行异步任务 ```rust #[tokio::main] async fn main() { let data = fetch_data().await.unwrap(); println!("{}", data); } ``` 四、运行时选择策略 | 特性 | tokio | async-std | |-------------|------------------|-------------------| | 设计目标 | 高性能网络应用 | 更接近标准库体验 | | 定时器精度 | 毫秒级 | 秒级 | | 社区生态 | 丰富插件生态 | 逐渐增长 | | 适用场景 | 复杂网络服务 | CLI工具/简单服务 | 五、关键注意事项 1. 避免阻塞:同步代码需用`spawn_blocking`隔离 2. 生命周期:`.await`可能导致引用失效,需用`Arc`共享 3. Pin约束:自引用结构必须固定内存地址 4. 取消传播:`select!`宏可处理多任务竞争 学习路线建议: 1. 掌握Future基础 → 2. 理解executor/reactor协作 → 3. 熟悉常见运行时API → 4. 实践典型并发模式(如channel、semaphore)→ 5. 研究高级优化技巧(如零拷贝IO) 推荐实践项目: - 异步Web爬虫 - TCP聊天服务器 - 并行文件处理器 - 自定义Future实现 官方资源: - 《Rust异步编程指南》(官方文档) - tokio官网教程(含丰富示例) - async-book中文版(社区翻译)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值