mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-16 14:27:49 +00:00
fixed links
This commit is contained in:
@@ -159,7 +159,7 @@ pub enum Poll<T> {
|
||||
|
||||
Теперь мы знаем, как определяются футуры, и понимаем основную идею метода `poll`. Однако мы все еще не знаем, как эффективно работать с футурами. Проблема в том, что они представляют собой результаты асинхронных задач, которые могут быть еще недоступны. На практике, однако, нам часто нужны эти значения непосредственно для дальнейших вычислений. Поэтому возникает вопрос: как мы можем эффективно получить значение, когда оно нам нужно?
|
||||
|
||||
#### Ожидание Futures
|
||||
#### Ожидание Futures {#waiting-on-futures}
|
||||
|
||||
Один из возможных ответов — дождаться, пока футура исполнится. Это может выглядеть примерно так:
|
||||
|
||||
@@ -235,7 +235,7 @@ fn file_len() -> impl Future<Output = usize> {
|
||||
|
||||
[_Futures с нулевой стоимостью в Rust_]: https://aturon.github.io/blog/2016/08/11/futures/
|
||||
|
||||
##### Недостатки
|
||||
##### Недостатки {#drawbacks}
|
||||
|
||||
Хотя комбинаторы футур позволяют писать очень эффективный код, их может быть сложно использовать в некоторых ситуациях из-за системы типов и интерфейса на основе замыканий. Например, рассмотрим такой код:
|
||||
|
||||
@@ -305,7 +305,7 @@ async fn example(min_len: usize) -> String {
|
||||
|
||||
([Попробовать](https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=d93c28509a1c67661f31ff820281d434))
|
||||
|
||||
Эта функция - прямой перевод `example` написанной [выше](#Недостатки), которая использовала комбинаторы. Используя оператор `.await`, мы можем получить значение футуры без необходимости использования каких-либо замыканий или типов `Either`. В результате мы можем писать наш код так же, как если бы это был обычный синхронный код, с той лишь разницей, что _это все еще асинхронный код_.
|
||||
Эта функция - прямой перевод `example` написанной [выше](#drawbacks), которая использовала комбинаторы. Используя оператор `.await`, мы можем получить значение футуры без необходимости использования каких-либо замыканий или типов `Either`. В результате мы можем писать наш код так же, как если бы это был обычный синхронный код, с той лишь разницей, что _это все еще асинхронный код_.
|
||||
|
||||
#### Преобразования Конечных Автоматов
|
||||
|
||||
@@ -504,7 +504,7 @@ fn example(min_len: usize) -> ExampleStateMachine {
|
||||
|
||||
Заметьте, что эта функция не запускает автомат. Это фундаментальное архитектурное решение для футур в Rust: они ничего не делают, пока не будет произведена первая проверка на готовность.
|
||||
|
||||
#### Закрепление
|
||||
#### Закрепление {#pinning}
|
||||
|
||||
Мы уже несколько раз столкнулись с понятием _закрепления_ (pinnig, пиннинг) в этом посте. Наконец, время, чтобы изучить, что такое закрепление и почему оно необходимо.
|
||||
|
||||
@@ -731,7 +731,7 @@ fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output>
|
||||
|
||||
Используя async/await, можно эргономично работать с футурами в полностью асинхронном режиме. Однако, как мы узнали выше, футуры ничего не делают, пока их не вызовут. Это означает, что нам нужно в какой-то момент вызвать `poll`, иначе асинхронный код никогда не будет выполнен.
|
||||
|
||||
Запуская одну футуры, мы можем вручную ожидать ее исполнения в цикле, [как описано выше](#ожидание-futures). Однако этот подход очень неэффективен и непрактичен для программ, создающих большое количество футур. Наиболее распространённым решением этого является создание глобального _исполнителя_ (executor), который отвечает за опрос (polling) всех футур в системе, пока они не завершатся.
|
||||
Запуская одну футуры, мы можем вручную ожидать ее исполнения в цикле, [как описано выше](#waiting-on-futures). Однако этот подход очень неэффективен и непрактичен для программ, создающих большое количество футур. Наиболее распространённым решением этого является создание глобального _исполнителя_ (executor), который отвечает за опрос (polling) всех футур в системе, пока они не завершатся.
|
||||
|
||||
#### Исполнитель
|
||||
|
||||
@@ -830,7 +830,7 @@ pub struct Task {
|
||||
|
||||
[_trait object_]: https://doc.rust-lang.org/book/ch17-02-trait-objects.html
|
||||
[_dynamically dispatched_]: https://doc.rust-lang.org/book/ch17-02-trait-objects.html#trait-objects-perform-dynamic-dispatch
|
||||
[разделе о закреплении]: #Закрепление
|
||||
[разделе о закреплении]: #pinning
|
||||
|
||||
Чтобы разрешить создание новых структур `Task` из футур, мы создаём функцию `new`:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user