Skip to content

Commit

Permalink
Merge pull request #89 from huangjj27/update-trans-2022-06-25
Browse files Browse the repository at this point in the history
Update trans 2022 06 25
  • Loading branch information
huangjj27 authored Jun 25, 2022
2 parents 6549c83 + e61f690 commit d461da2
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 8 deletions.
2 changes: 1 addition & 1 deletion src_zh-CN/01_getting_started/02_why_async.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

尽管很多语言都支持异步编程,但实现细节上有很多不一样。Rust 的异步实现和大部分语言的在以下方面有区别:

- Rust 中 **插入了Futures**,并且只有被轮询才会进一步执行。丢弃(Dropping)一个 future 可以阻止它继续执行。
- Rust 中 **Futures 是惰性的**,并且只有被轮询才会进一步执行。丢弃(Dropping)一个 future 可以阻止它继续执行。
- Rust 中的 **异步是零成本**的,这意味着你只需要为你所使用的东西付出代价。特别来说,你使用异步时可以不需要堆分配或动态分发,这对性能来说是好事!这也使得你能够在约束环境下使用异步,例如嵌入式系统。
- Rust **不提供内置运行时**。相反,运行时由社区维护的库提供。
- Rust里 **单线程的和多线程的** 运行时都可用,而他们会有不同的优劣。
Expand Down
4 changes: 1 addition & 3 deletions src_zh-CN/02_execution/02_future.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

Future 能通过调用 `poll` 的方式推进,这会尽可能地推进 future 到完成状态。如果 future 完成了, 那就会返回 `poll::Ready(result)`。如果 future 尚未完成,则返回 `poll::Pending`,并且安排 `wake()` 函数在 `Future` 准备好进一步执行时调用(译者注:注册回调函数)。当 `wake()` 调用 时,驱动 `Future` 的执行器会再次 `poll` 使得 `Future` 有所进展。

没有 `wake()` 函数的话,执行器将无从获知一个future 是否能有所进展,并且会持续轮询(polling) 所有 future。但有了 `wake()` 函数,执行器就能知道哪些 future 已经准备好轮询了。
没有 `wake()` 函数的话,执行器将无从获知一个 future 是否能有所进展,只能持续轮询(polling) 所有 future。但有了 `wake()` 函数,执行器就能知道哪些 future 已经准备好轮询了。

例如,考虑一下场景:我们准备读取一个套接字(socket),它可能还没有可以返回的数据。如果它有 数据了,我们可以读取数据并返回 `poll::Ready(data)`,但如果数据没有准备好,我们这个future 就会阻塞并且不能继续执行。当没有数据可用时,我们需要注册 `wake` 函数,以在有数据可用时告诉执行 器我们的 future 准备好进一步操作。一个简单的 `SocketRead`future 可能像这样:

Expand Down Expand Up @@ -39,5 +39,3 @@ Futures的这种模型允许组合多个异步操作而无需立刻分配资源
然后 `wake: fn()` 变成了 `&mut Context<'_>`。在 `SimpleFuture` 里,我们调用函数指针(`fn()`) 来告诉执行器有future需要轮询。然而,因为 `fn()` 是仅仅是个函数指针,它不能储存任何信息说明哪个 `Future` 调用了 `wake`

在现实场景中,像Web服务器这样复杂的应用可能有上千不同的连接,带有应该相互隔离来管理的 唤醒器(wakeups)。`Context` 类型通过提供对 `waker` 类型的访问来解决这个问题,这些 `waker` 会唤起持定任务。


8 changes: 4 additions & 4 deletions src_zh-CN/04_pinning/01_chapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ fn main() {

我们来看看固定和 `Pin` 类型如何帮助我们解决这个问题。

`Pin` 类型包装了指针类型, 保证指针指向的值不会被移动。例如, `Pin<&mut T>`, `Pin<&T>`, `Pin<Box<T>>` 都保证了 `T` 不会被移动,即使 `T: !Unpin`.
`Pin` 类型包装了指针类型, 保证没有实现 `Unpin` 指针指向的值不会被移动。例如, `Pin<&mut T>`, `Pin<&T>`, `Pin<Box<T>>` 都保证了 `T` 不会被移动,即使 `T: !Unpin`.

多数类型被移走也不会有问题。这些类型实现了 `Unpin` trait。指向 `Unpin` 类型的指针能够自由地放进 `Pin`,或取走。例如,`u8``Unpin` 的,所以 `Pin<&mut T>` 的行为就像普通的 `&mut T`,就像普通的 `&mut u8`

Expand Down Expand Up @@ -525,17 +525,17 @@ impl Test {
_marker: PhantomPinned,
};
let mut boxed = Box::pin(t);
let self_ptr: *const String = &boxed.as_ref().a;
let self_ptr: *const String = &boxed.a;
unsafe { boxed.as_mut().get_unchecked_mut().b = self_ptr };
boxed
}
fn a<'a>(self: Pin<&'a Self>) -> &'a str {
fn a(self: Pin<&Self>) -> &str {
&self.get_ref().a
}
fn b<'a>(self: Pin<&'a Self>) -> &'a String {
fn b(self: Pin<&Self>) -> &String {
unsafe { &*(self.b) }
}
}
Expand Down
6 changes: 6 additions & 0 deletions src_zh-CN/12_appendix/01_translations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# 附录:本书翻译

本书其他语言版本的资源:

- [俄语](https://doc.rust-lang.ru/async-book/)
- [法语](https://jimskapt.github.io/async-book-fr/)

0 comments on commit d461da2

Please sign in to comment.