1# ylong_runtime 用户指南 2 3ylong_runtime提供了异步任务生成以及调度的能力,同时异步化了各类系统IO,并提供了同步原语,定时器功能。 4 5ylong_runtime 整体分为4个库: 6 7- ylong_ffrt: Function Flow Runtime的FFI层 8- ylong_io: 事件驱动型网络IO库 9- ylong_runtime: 异步调度框架库 10- ylong_runtime_macros:调度框架宏库 11 12其中 ylong_runtime 承载了异步调度框架的主体功能,并且依赖其余三个库提供的底层能力。 13 14如果需要查看详细的接口说明请查看对应接口的 docs,可以使用 `cargo doc --open` 生成并查看 docs。 15 16## 配置异步调度框架 17 18可以链式设置runtime的具体配置。必须在`block_on`,`spawn`之前设置,否则`runtime`会使用默认配置。 相关接口位于`ylong_runtime::builder`. 19 20```rust 21fn main() { 22 let _ = ylong_runtime::builder::RuntimeBuilder::new_multi_thread() 23 .worker_stack_size(10) 24 .keep_alive_time(std::time::Duration::from_secs(10)) 25 .build_global(); 26 27 let fut = async { 28 29 }; 30 let _ = ylong_runtime::block_on(fut); 31} 32``` 33 34## 生成异步任务 35 36通过``spawn``生成异步任务 37 38```rust 39fn main() { 40 let handle = ylong_runtime::spawn(async move { 41 // 嵌套生成异步任务 42 let handle = ylong_runtime::spawn(async move { 43 1 44 }); 45 46 // 在异步上下文使用await异步等待任务完成 47 let res = handle.await.unwrap(); 48 assert_eq!(res, 1); 49 1 50 }); 51 // 在同步上下文使用block_on阻塞等待异步任务完成 52 let res = ylong_runtime::block_on(handle).unwrap(); 53 assert_eq!(res, 1); 54} 55 56``` 57 58## 生成非异步任务 59 60通过``spawn_blocking``生成任务 61 62```rust 63fn main() { 64 let fut = async { 65 // 这里可以是闭包也可以是函数。 66 let join_handle = ylong_runtime::spawn_blocking(|| {}); 67 // 等待任务执行完成 68 let _result = join_handle.await; 69 }; 70 let _ = ylong_runtime::block_on(fut); 71} 72 73``` 74 75## 取消异步任务 76 77通过``join_handle``的``cancel``接口取消任务。如果任务成功取消,等待该任务将立即返回一个错误。 78 79```rust 80use std::time::Duration; 81use ylong_runtime::error::ErrorKind; 82use ylong_runtime::time::sleep; 83 84fn main() { 85 let handle = ylong_runtime::spawn(async move { 86 let task = ylong_runtime::spawn(async move { 87 sleep(Duration::from_secs(100)).await; 88 }); 89 task.cancel(); 90 let res = task.await.err().unwrap(); 91 assert_eq!(res.kind(), ErrorKind::TaskCanceled); 92 }); 93 ylong_runtime::block_on(handle).unwrap(); 94} 95``` 96 97## 使用网络异步IO 98 99使用 ylong_runtime 中封装的异步IO(TCP/UDP)进行网络连接,相关接口定义位于模块 `ylong_runtime::net`. 100 101```rust 102use ylong_runtime::net::{TcpListener, TcpStream}; 103use ylong_runtime::io::AsyncWrite; 104 105fn main() { 106 let addr = "127.0.0.1:8081".parse().unwrap(); 107 let handle = ylong_runtime::spawn(async move { 108 // 异步TCP服务端,监听一个端口 109 let listener = TcpListener::bind(addr).await; 110 if let Err(e) = listener { 111 assert_eq!(0, 1, "Bind Listener Failed {e}"); 112 } 113 114 let listener = listener.unwrap(); 115 // 接受一个TCP连接请求 116 let mut socket = match listener.accept().await { 117 Ok((socket, _)) => socket, 118 Err(e) => { 119 assert_eq!(0, 1, "Bind accept Failed {e}"); 120 } 121 }; 122 123 // 发送一条信息给客户端 124 if let Err(e) = socket.write(b"hello client").await { 125 assert_eq!(0, 1, "failed to write to socket {e}"); 126 } 127 }); 128} 129 130``` 131 132## 使用定时器 133定时器相关接口位于模块`ylong_runtime::time`. 里面包括了任务睡眠,任务超时,以及周期性定时器的功能。 134 135```rust 136use std::time::Duration; 137use ylong_runtime::time::{timeout, sleep}; 138 139fn main() { 140 let handle = ylong_runtime::spawn(async move { 141 // 这个任务将在100微秒后超时,任务在这个时间内完成将返回结果。 142 let result = timeout(Duration::from_millis(100), async { 1 }).await; 143 assert_eq!(result.unwrap(), 1); 144 145 // 如果任务超时,将返回一个超时错误。 146 let result = timeout(Duration::from_millis(100), sleep(Duration::from_secs(1))); 147 assert!(result.is_err()); 148 }); 149} 150 151 152``` 153 154## 使用ParIter 155 156`ParIter` 及其相关接口定义于模块 `ylong_runtime::iter`,`ParIter`支持数据在线程中做并行迭代,一组数据会在线程中被分割,分割后的数据会在线程中并行执行迭代器中的操作。 157 158```rust 159use ylong_runtime::iter::prelude::*; 160 161fn main() { 162 ylong_runtime::block_on(fut()); 163} 164 165async fn fut() { 166 let v = (1..30).into_iter().collect::<Vec<usize>>(); 167 let sum = v.par_iter().map(|x| fibbo(*x)).sum().await.unwrap(); 168 println!("{}", sum); 169} 170 171fn fibbo(i: usize) -> usize { 172 match i { 173 0 => 1, 174 1 => 1, 175 n => fibbo(n - 1) + fibbo(n - 2), 176 } 177} 178```