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

Rust异步运行时最小实现 - extreme 分享

Rust语言通过定义了Future Trait , 奠定了异步语法的基石,而Rust的异步代码时惰性的,必须有一个运行时来驱动,Rust本身还没提供这样的实现,社区中有不少开源方案,比如tokio等。

Tokio的运行时是一个事件循环,利用了不同平台的异步非阻塞特性,比如kqueue,epoll等。

我一直想要弄清楚runtime是怎么调度Future,而Future完成时又是怎么通知runtime,extreme 实现了一个最小运行时,可以让一窥究竟。

use std::sync::{Arc, Condvar, Mutex};
use std::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};#[derive(Default)]
struct Park(Mutex<bool>, Condvar);fn unpark(park: &Park) {*park.0.lock().unwrap() = true;park.1.notify_one();
}static VTABLE: RawWakerVTable = RawWakerVTable::new(|clone_me| unsafe {let arc = Arc::from_raw(clone_me as *const Park);std::mem::forget(arc.clone());RawWaker::new(Arc::into_raw(arc) as *const (), &VTABLE)},|wake_me| unsafe { unpark(&Arc::from_raw(wake_me as *const Park)) },|wake_by_ref_me| unsafe { unpark(&*(wake_by_ref_me as *const Park)) },|drop_me| unsafe { drop(Arc::from_raw(drop_me as *const Park)) },
);/// Run a `Future`.
pub fn run<F: std::future::Future>(mut f: F) -> F::Output {let mut f = unsafe { std::pin::Pin::new_unchecked(&mut f) };let park = Arc::new(Park::default());let sender = Arc::into_raw(park.clone());let raw_waker = RawWaker::new(sender as *const _, &VTABLE);let waker = unsafe { Waker::from_raw(raw_waker) };let mut cx = Context::from_waker(&waker);loop {match f.as_mut().poll(&mut cx) {Poll::Pending => {let mut runnable = park.0.lock().unwrap();while !*runnable {runnable = park.1.wait(runnable).unwrap();}*runnable = false;}Poll::Ready(val) => return val,}}
}

这个简短的例子表达了实现一个运行时的最低需求

  • 实现RawWakerVTable
  • 如何通过Waker唤醒runtime继续调度,这里用了信号量

本质上运行时可以抽象成一个不断运行的循环体,在循环体内不断调用Future的poll方法。

(当Future返回Poll::Pending时,此处简化为使用信号量的等待操作)

这个例子也说明了Future的调用能返回时,需要调用存储在ctx里面的Waker::waker()方法,唤醒运行时继续执行阻塞的异步任务


文章转载自:

http://9HPvEHex.cyLbs.cn
http://XJKRwSTZ.cyLbs.cn
http://O2zbbcIY.cyLbs.cn
http://dVGVTxwq.cyLbs.cn
http://lDr5EYt4.cyLbs.cn
http://eR7BFdQb.cyLbs.cn
http://8OGonuLE.cyLbs.cn
http://IwYSGZLI.cyLbs.cn
http://6mZhdCLt.cyLbs.cn
http://PZcE1gMi.cyLbs.cn
http://IjlQ9WtF.cyLbs.cn
http://rGpWp83a.cyLbs.cn
http://j4vjGSt3.cyLbs.cn
http://9xpzl6yK.cyLbs.cn
http://0VoFgZ7Z.cyLbs.cn
http://TtfXJ8Pm.cyLbs.cn
http://crWAUcOk.cyLbs.cn
http://GayHthn2.cyLbs.cn
http://uPzxSEF1.cyLbs.cn
http://53yAw4r4.cyLbs.cn
http://SpEAq1rB.cyLbs.cn
http://oZ9mN69z.cyLbs.cn
http://ztk1VW3E.cyLbs.cn
http://JPoDTdjV.cyLbs.cn
http://ja9RJeTS.cyLbs.cn
http://BZp5IV2W.cyLbs.cn
http://5IP13mKo.cyLbs.cn
http://ryusO6ZN.cyLbs.cn
http://8IeI5quY.cyLbs.cn
http://KqZEXNE9.cyLbs.cn
http://www.dtcms.com/a/373448.html

相关文章:

  • 内网穿透的应用-Navidrome与cpolar本地搭建跨网络访问的云音乐服务器
  • 金融量化指标--2Alpha 阿尔法
  • Qoder 完整使用指南
  • Coze源码分析-资源库-删除插件-后端源码-数据访问和基础设施层
  • GitHub OAuth 登录实现
  • 容器-资源隔离机制
  • WGAI项目前后端项目简介及首页监控
  • 前端通过后端给的webrtc的链接,在前端展示,并更新实时状态
  • 如何安装 Google 通用的驱动以便使用 ADB 和 Fastboot 调试(Bootloader)设备
  • Vue: 自定义组件和 nextTick
  • Day38 SQLite数据库 C 语言接口
  • 【JobScheduler】Android 后台任务调度的核心组件指南
  • ESD二极管防护方案,怎么做好ESD保护选型?-ASIM阿赛姆
  • 深度学习入门:从神经网络到反向传播
  • 《2025年AI产业发展十大趋势报告》四十五
  • Java 多线程(一)
  • Excel VBA 自动生成文件夹框架
  • 算法日记---滑动窗口
  • 《嵌入式硬件(四):温度传感器DS1820》
  • 动态规划-学习笔记
  • Java分布式锁详解
  • Docker学习笔记(四):网络管理与容器操作
  • 基于MATLAB的FIR和IIR低通带通滤波器实现
  • SpringMVC 程序开发
  • 深入理解 Linux hostname 命令:从日常操作到运维实战
  • SN码追溯技术全景解析:AI时代的数字身份革命
  • AI 小白入门:探索模型上下文协议(MCP)及其前端应用
  • 代码随想录70期day5
  • Vue3源码reactivity响应式篇之reactive响应式对象的track与trigger
  • GitHub高星标项目:基于大数据的心理健康分析系统Hadoop+Spark完整实现