-
Notifications
You must be signed in to change notification settings - Fork 441
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
77 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
# 第四阶段总结报告 | ||
|
||
### 一些碎语 | ||
我查看了三篇文档 , 其中https://os.phil-opp.com/async-await/#pinning | ||
|
||
新使用的crate:crossbeam ,conquer_once | ||
|
||
为啥使用conquer_once的OnceCell而不是lazy_static!因为这个类型实现 | ||
了避免中断程序进行堆空间开辟(从而避免产生一个死锁) | ||
|
||
future 中还有一个Stream的trait | ||
tokio文档看了一下(trait回忆一下,它像个接口,implement后应用到具体的一个类型) | ||
|
||
## Tokio 文档阅读 | ||
|
||
### chat | ||
首先阅读的是一堆example,这里先看chat。 | ||
chat是一个聊天室,设立服务端然后异步读取其他客户端的消息,并且广播到是所有的客户端, | ||
是一种中心式结构 | ||
|
||
|
||
## io_uring | ||
|
||
### 与linux | ||
linux有一个自己的原生异步IO接口,叫aio,他有一些问题: | ||
1. 因为0_DIRECT,所以很多的IO用例不适用。普通的IO会退化为同步IO。 | ||
2. 就算异步,IO也可能会阻塞,比如硬件部分,这使得软件必须获取加载这些部分的锡信息 | ||
3. API不够完美,每次提交需要64+8字节的内存,每次完成徐娅萍 | ||
他常用的方法是:io_submit() , io_setup() , io_getevents(). | ||
|
||
|
||
|
||
### io-uring 和 epoll。 | ||
|
||
epoll 只是通知机制,本质上事情还是通过用户代码直接 syscall 来做的,如 read。这样在高频 | ||
syscall 的场景下,频繁的用户态内核态切换会消耗较多资源。io-uring 可以做异步 syscall, | ||
即便是不开 SQ_POLL 也可以大大减少 syscall 次数。 | ||
|
||
io-uring 的问题在于下面几点: | ||
|
||
**兼容问题**。平台兼容就不说了,linux only(epoll 在其他平台上有类似的存在,可以基于已 | ||
经十分完善的 mio 做无缝兼容)。linux 上也会对 kernel 版本有一定要求,且不同版本的实现性 | ||
能还有一定差距。大型公司一般还会有自己修改的内核版本,所以想持续跟进 backport 也是一件头疼 | ||
事。同时对于 Mac/Windows 用户,在开发体验上也会带来一定困难。 | ||
|
||
**Buffer 生命周期问题**。io-uring 是全异步的,Op push 到 SQ 后就不能移动 buffer,一定 | ||
要保证其有效,直到 syscall 完成或 Cancel Op 执行完毕。无论是在 C/C++ 还是 Rust 中,都 | ||
会面临 buffer 生命周期管理问题。epoll 没有这个问题,因为 syscall 就是用户做的,陷入 sy | ||
scall 期间本来就无法操作 buffer,所以可以保证其持续有效直到 syscall 返回。 | ||
|
||
## smol | ||
在几个库的基础上封装成最后几个接口 | ||
|
||
在 Linux 上,mio 使用 epoll 来实现高效的 I/O 多路复用。smol 使用 mio 来实现 | ||
这一点。具体来说,smol 会将 I/O 操作抽象为异步任务,然后将这些任务交给 mio 处理。 | ||
mio 通过 epoll 监听文件描述符,当某个文件描述符变得可读或可写时,它会通知 smol 来 | ||
执行相应的任务。 | ||
|
||
在 smol 的源码中,底层通过调用 mio 提供的异步 I/O API 来实现任务的异步调度。例如 | ||
,读取数据时,它会发出 epoll 查询,直到某个文件描述符准备好读取数据,才会从事件队列中获 | ||
取该事件并执行对应的异步任务。 | ||
|
||
|
||
## 关于我的运行时 | ||
用proactor包装io_uring实现基本的异步读写,然后再包装proactor实现io和file,然后没有什么了, | ||
一开始低估了整个运行时的大小 | ||
|
||
然后看了很多的文档: | ||
|
||
https://github.com/rust-lang/futures-rs/blob/master/futures-core/src/stream.rs | ||
https://rustmagazine.github.io/rust_magazine_2021/chapter_12/monoio.html | ||
https://github.com/bytedance/monoio/blob/master/docs/zh/io-cancel.md | ||
https://github.com/ihciah/mini-rust-runtime/blob/master/src/tcp.rs | ||
https://github.com/rust-lang/futures-rs/blob/master/futures-core/src/lib.rs | ||
|
||
这里我认为monoio算是一个正确的,完善的运行时,不过这个大小太夸张了,可以下期一开始就把它粘出来,让大家 | ||
直观感受一下成果的规模。 |