readme update

Signed-off-by: MingyuChen <chenmingyu4@huawei.com>
This commit is contained in:
MingyuChen 2023-06-26 10:35:57 +08:00
parent 86f3eaf4d0
commit 4545d26ffa
6 changed files with 286 additions and 94 deletions

View File

@ -1,24 +1,66 @@
# ylong_runtime
## Introduction
Rust language doesn't provide an asynchronous runtime. Instead, it provides basic primitives and functionalities such as ``async``, ``await``, ``Future``, and ``Waker``. Therefore, it's users' responsibilities to implement the runtime, or choose from an existing third party's runtime.
Rust asynchronous runtime, provides functionalities such as spawning async tasks, async io, synchronization, parallel calculation.
### Overall structure
![structure](./figure/structure.png)
## Compile Build
1. Introduce ylong_runtime in Cargo.toml
Method 1: Introduce ylong_runtime in Cargo.toml
```toml
#[dependence]
ylong_runtime = { git = "https://gitee.com/openharmony-sig/commonlibrary_rust_ylong_runtime.git", version = "1.9.0", features = ["full"]}
```
2. Add dependencies to BUILD.gn where appropriate
For compiling FFRT version of ylong_runtime, rename ``ylong_ffrt/build_ffrt.rs`` to ``ylong_ffrt/build.rs``, and export `LD_LIBRARY_PATH`
Method 2: Add dependencies to BUILD.gn where appropriate
```
deps += ["//commonlibrary/rust/ylong_runtime/ylong_runtime:ylong_runtime"]
deps += ["//commonlibrary/rust/ylong_runtime/ylong_runtime:lib"]
```
## directory
```
ylong_runtime
|── ylong_ffrt
| └── src # FFRT rust ffi
|── ylong_io
| |── exmaples # Examples of ylong_io
| |── src # Source code of ylong_io
| | └── sys # OS specific implementation
| | |── linux # Epoll driven io
| | └── windows # Iocp driven io
|── ylong_runtime
| |── benches # Benchmarks of ylong_runtime
| |── examples # Examples of ylong_runtime
| |── src # Source code of ylong_runtime
| | |── builder # Runtime builder
| | |── executor # Runtime executor
| | |── ffrt # FFRT adapter
| | |── fs # Async fs components
| | |── io # Async io traits and components
| | | └── buffered # Async BufReader and BufWriter
| | |── iter # Async parallel iterator
| | | |── parallel # ParIter implementation for data containers
| | | └── pariter # Core of pariter
| | |── net # Async net io and net driver
| | | └── sys # Async system io
| | | └── tcp # Async Tcp
| | |── sync # Runtime synchronization components
| | | └── mpsc # Mpsc channels
| | |── task # Async task components
| | |── time # Timer components
| | └── util # Utilities
| | |── core_affinity # Vore affinity components
| | └── num_cpus # Num cpus components
| └── tests # Sdv of ylong_runtime
└── ylong_runtime_macros # Macros for runtime
```
## Usage
@ -101,6 +143,10 @@ fn fibbo(i: usize) -> usize {
}
```
## User Guide
See [user_guide](./docs/user_guide.md)
## Acknowledgements
Based on the user's habit, the API of this library, after changing the original Rust standard library synchronous interface implementation to asynchronous, retains the original naming style of the standard library, such as``TcpStream::connect``, ``File::read``, ``File::write`` and so on. We also refer to some of Tokio's general API design ideas, and we would like to express our gratitude to the Rust standard library and Tokio

View File

@ -1,109 +1,69 @@
# ylong_runtime
## 简介
Rust语言在提供了``async``/``await``, ``Future``, ``Waker``等异步基础组件的同时,并不提供具体的异步运行时实现。而具体实现则需要用户自己构建,或者使用社区已构建好的异步运行时。这样的好处是用户可以在自己的使用场景做定制化的优化。
Rust异步运行时库用于生成并执行异步任务。主要分为Time, Sync, Parallel calculation, IO四个模块。
### 图一 整体架构图
![structure](./figure/structure.png)
## 目录
```
ylong_runtime
|── ylong_ffrt
| └── src # FFRT ffi封装
|── ylong_io
| |── exmaples # ylong_io 代码示例
| |── src # ylong_io 源码
| | └── sys # 操作系统相关io实现
| | |── linux # Linux 事件驱动IO实现
| | └── windows # Windows 事件驱动IO实现
|── ylong_runtime
| |── benches # ylong_runtime 性能用例
| |── examples # ylong_runtime 代码示例
| |── src # ylong_runtime 源码
| | |── builder # Runtime builder实现
| | |── executor # Runtime executor实现
| | |── ffrt # FFRT 适配
| | |── fs # 异步文件IO实现
| | |── io # 异步IO接口以及对外API
| | | └── buffered # 异步缓存读写实现
| | |── iter # 异步并行迭代器实现
| | | |── parallel # 数据容器适配
| | | └── pariter # 并行迭代核心业务实现
| | |── net # 异步网络IO/Driver实现
| | | └── sys # 系统IO异步实现
| | | └── tcp # 异步TCP实现
| | |── sync # 异步同步原语
| | | └── mpsc # 单生产者多消费者通道实现
| | |── task # 异步任务实现
| | |── time # 定时器实现
| | └── util # 公共组件
| | |── core_affinity # 绑核实现
| | └── num_cpus # 获取核数实现
| └── tests # ylong_runtime 测试用例
└── ylong_runtime_macros # ylong_runtime 宏实现
```
## 编译构建
1. 在Cargo.toml中引入ylong_runtime
方法一:在Cargo.toml中引入ylong_runtime
```toml
#[dependence]
ylong_runtime = { git = "https://gitee.com/openharmony-sig/commonlibrary_rust_ylong_runtime.git", version = "1.9.0", features = ["full"]}
```
2. 在 BUILD.gn 合适的地方添加依赖
如果需要编译ffrt版本将ylong_ffrt目录下的``build_ffrt.rs``文件重命名为``build.rs``, 并设置`LD_LIBRARY_PATH`
方法二:在 BUILD.gn 合适的地方添加依赖
```
deps += ["//commonlibrary/rust/ylong_runtime/ylong_runtime:ylong_runtime"]
```
## 使用说明
### `ylong` 全局线程池
```rust
use std::net::{Ipv4Addr, SocketAddrV4};
use ylong_runtime::io::*;
use ylong_runtime::net::TcpListener;
fn main() -> std::io::Result<()> {
ylong_runtime::block_on(async {
let ip = Ipv4Addr::new(127, 0, 0, 1);
let addr = SocketAddrV4::new(ip, 8080);
let listener = TcpListener::bind(addr.into()).await?;
loop {
let (mut stream, _) = listener.accept().await?;
stream.write_all("hello ylong".as_bytes());
}
})
}
```
#### 线程池设置
可以链式设置runtime的具体配置。必须在`block_on``spawn`之前设置,否则`runtime`会使用默认配置。
```rust
fn main() {
let _ = ylong_runtime::builder::RuntimeBuilder::new_multi_thread()
.worker_stack_size(10)
.keep_alive_time(std::time::Duration::from_secs(10))
.build_global();
let fut = async {
};
let _ = ylong_runtime::block_on(fut);
}
```
### `ylong` 调度框架非异步线程池(spawn_blocking)使用
```rust
fn main() {
let fut = async {
// 这里可以是闭包也可以是函数。
let join_handle = ylong_runtime::spawn_blocking(|| {});
// 等待任务执行完成
let _result = join_handle.await;
};
let _ = ylong_runtime::block_on(fut);
}
```
### ParIter 功能介绍
`ParIter` 及其相关接口定义于模块 `ylong_runtime::iter``ParIter`支持数据在线程中做并行迭代,一组数据会在线程中被分割,分割后的数据会在线程中并行执行迭代器中的操作。
```rust
use ylong_runtime::iter::prelude::*;
fn main() {
ylong_runtime::block_on(fut());
}
async fn fut() {
let v = (1..30).into_iter().collect::<Vec<usize>>();
let sum = v.par_iter().map(|x| fibbo(*x)).sum().await.unwrap();
println!("{}", sum);
}
fn fibbo(i: usize) -> usize {
match i {
0 => 1,
1 => 1,
n => fibbo(n - 1) + fibbo(n - 2),
}
}
deps += ["//commonlibrary/rust/ylong_runtime/ylong_runtime:lib"]
```
## 用户指南
详情内容请见[用户指南](./docs/user_guide.md)
## 致谢

8
RELEASE_NOTES.md Normal file
View File

@ -0,0 +1,8 @@
# 1.0.0
1. ylong_runtime initial version, which provides these features:
- spawning async tasks and asynchronously waiting on them
- async net: tcp / udp
- async fs: file/directory creation, read/write
- time: timeout and periodic timer
- sync: mutex, mpsc channels, semaphore, notify
- par_iter: asynchronous parallel iterator

178
docs/user_guide.md Normal file
View File

@ -0,0 +1,178 @@
# ylong_runtime 用户指南
ylong_runtime提供了异步任务生成以及调度的能力同时异步化了各类系统IO并提供了同步原语定时器功能。
ylong_runtime 整体分为4个库
- ylong_ffrt: Function Flow Runtime的FFI层
- ylong_io: 事件驱动型网络IO库
- ylong_runtime: 异步调度框架库
- ylong_runtime_macros调度框架宏库
其中 ylong_runtime 承载了异步调度框架的主体功能,并且依赖其余三个库提供的底层能力。
如果需要查看详细的接口说明请查看对应接口的 docs可以使用 `cargo doc --open` 生成并查看 docs。
## 配置异步调度框架
可以链式设置runtime的具体配置。必须在`block_on``spawn`之前设置,否则`runtime`会使用默认配置。 相关接口位于`ylong_runtime::builder`.
```rust
fn main() {
let _ = ylong_runtime::builder::RuntimeBuilder::new_multi_thread()
.worker_stack_size(10)
.keep_alive_time(std::time::Duration::from_secs(10))
.build_global();
let fut = async {
};
let _ = ylong_runtime::block_on(fut);
}
```
## 生成异步任务
通过``spawn``生成异步任务
```rust
fn main() {
let handle = ylong_runtime::spawn(async move {
// 嵌套生成异步任务
let handle = ylong_runtime::spawn(async move {
1
});
// 在异步上下文使用await异步等待任务完成
let res = handle.await.unwrap();
assert_eq!(res, 1);
1
});
// 在同步上下文使用block_on阻塞等待异步任务完成
let res = ylong_runtime::block_on(handle).unwrap();
assert_eq!(res, 1);
}
```
## 生成非异步任务
通过``spawn_blocking``生成任务
```rust
fn main() {
let fut = async {
// 这里可以是闭包也可以是函数。
let join_handle = ylong_runtime::spawn_blocking(|| {});
// 等待任务执行完成
let _result = join_handle.await;
};
let _ = ylong_runtime::block_on(fut);
}
```
## 取消异步任务
通过``join_handle``的``cancel``接口取消任务。如果任务成功取消,等待该任务将立即返回一个错误。
```rust
use std::time::Duration;
use ylong_runtime::error::ErrorKind;
use ylong_runtime::time::sleep;
fn main() {
let handle = ylong_runtime::spawn(async move {
let task = ylong_runtime::spawn(async move {
sleep(Duration::from_secs(100)).await;
});
task.cancel();
let res = task.await.err().unwrap();
assert_eq!(res.kind(), ErrorKind::TaskCanceled);
});
ylong_runtime::block_on(handle).unwrap();
}
```
## 使用网络异步IO
使用 ylong_runtime 中封装的异步IO(TCP/UDP)进行网络连接,相关接口定义位于模块 `ylong_runtime::net`.
```rust
use ylong_runtime::net::{TcpListener, TcpStream};
use ylong_runtime::io::AsyncWrite;
fn main() {
let addr = "127.0.0.1:8081".parse().unwrap();
let handle = ylong_runtime::spawn(async move {
// 异步TCP服务端监听一个端口
let listener = TcpListener::bind(addr).await;
if let Err(e) = listener {
assert_eq!(0, 1, "Bind Listener Failed {e}");
}
let listener = listener.unwrap();
// 接受一个TCP连接请求
let mut socket = match listener.accept().await {
Ok((socket, _)) => socket,
Err(e) => {
assert_eq!(0, 1, "Bind accept Failed {e}");
}
};
// 发送一条信息给客户端
if let Err(e) = socket.write(b"hello client").await {
assert_eq!(0, 1, "failed to write to socket {e}");
}
});
}
```
## 使用定时器
定时器相关接口位于模块`ylong_runtime::time`. 里面包括了任务睡眠,任务超时,以及周期性定时器的功能。
```rust
use std::time::Duration;
use ylong_runtime::time::{timeout, sleep};
fn main() {
let handle = ylong_runtime::spawn(async move {
// 这个任务将在100微秒后超时任务在这个时间内完成将返回结果。
let result = timeout(Duration::from_millis(100), async { 1 }).await;
assert_eq!(result.unwrap(), 1);
// 如果任务超时,将返回一个超时错误。
let result = timeout(Duration::from_millis(100), sleep(Duration::from_secs(1)));
assert!(result.is_err());
});
}
```
## 使用ParIter
`ParIter` 及其相关接口定义于模块 `ylong_runtime::iter``ParIter`支持数据在线程中做并行迭代,一组数据会在线程中被分割,分割后的数据会在线程中并行执行迭代器中的操作。
```rust
use ylong_runtime::iter::prelude::*;
fn main() {
ylong_runtime::block_on(fut());
}
async fn fut() {
let v = (1..30).into_iter().collect::<Vec<usize>>();
let sum = v.par_iter().map(|x| fibbo(*x)).sum().await.unwrap();
println!("{}", sum);
}
fn fibbo(i: usize) -> usize {
match i {
0 => 1,
1 => 1,
n => fibbo(n - 1) + fibbo(n - 2),
}
}
```

BIN
figure/structure.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB