sui_rust/ch03/
s2_async_await.rs

1//! 第三章:Rust 异步编程概念
2//!
3//! # 3.2 异步 编程 模型
4//!
5//! - [smol](https://github.com/smol-rs/smol)
6//! - Future
7//! - 生成器 与 协程
8//! - Pin 与 UnPin
9//! - Async/Await
10//!
11//!
12
13/**
14
15    让我们先从建立异步编程模型的整体概念框架开始,先不深入细节。
16
17    **Rust 提供的异步并发相比于其他语言有什么特点?**
18
19    1. Rust 语言只是提供一个零成本的异步编程抽象,而不内置运行时。
20    2. 基于 Generator 实现的 Future,在 Future 基础上 提供 async/await 语法糖。本质是一个状态机。
21
22    查看 README 和其他编程语言比较的图示。
23
24    **为什么需要异步?**
25
26    1. 对极致性能的追求。
27    2. 对编程体验的追求。
28
29    **异步编程模型发展阶段:**
30
31    1. Callback
32    2. Promise/Future
33    3. async/await
34
35    可在项目 README 查看回调地狱示例图。
36
37    ```text
38    A
39    +------+
40    |      |
41    |      |
42    |      +-------------------+
43    |      |                   |
44    |      |                   |
45    |      |                  Bv
46    +------+                +-----+
47    |      |                |     |
48    |      |                | do1 |
49    |      |                |     |
50    |      |                +-----+
51    |      |                |     |
52    |      |                | do2 |
53    |      |                +-+---+
54    |      |                  |
55    |      |                  |
56    | A    |                  |
57    +------+                  |
58    |      |                  |
59    |      |                  |
60    |      |                  |
61    |      | <----------------+
62    |      |
63    |      |
64    |      |
65    +------+
66
67    ```
68
69    早期 Rust 异步写法示意:
70
71    ```rust
72    let future = id_rpc(&my_server).and_then(|id| {
73        get_row(id)
74    }).map(|row| {
75        json::encode(row)
76    }).and_then(|encoded| {
77        write_string(my_socket, encoded)
78    });
79    ```
80
81    这样写会存在大量内嵌 Future,开发体验不好。
82
83    引入 async/await 之后:
84
85    ```rust
86    let id = id_rpc(&my_server).await;
87    let row = get_row(id).await;
88    let encoded = json::encode(row);
89    write_string(my_socket, encoded).await;
90    ```
91
92    拥有了和同步代码一致的体验。
93
94    **异步任务可看作是一种绿色线程**
95
96    查看 README 相关图示
97
98    可以说,异步任务的行为是模仿 线程 来抽象。
99
100    1. 线程在进程内,异步任务在线程内。
101    2. 线程可被调度切换(Linux默认抢占式),异步任务也可以被调度(协作式而非抢占式)。区别在于,异步任务只在用户态,没有线程的上下文切换开销。
102    3. 线程有上下文信息,异步任务也有上下文信息。
103    4. 线程间可以通信,异步任务之间也可以通信。
104    5. 线程间有竞争,异步任务之间也有竞争。
105
106    整个异步编程概念,包括异步语法、异步运行时都是围绕如何建立这种「绿色线程」抽象而成的。
107
108*/
109pub fn a_async_intro() {}
110
111/**
112
113    # Future 和 Futures-rs 概要
114
115    - [Future](https://doc.rust-lang.org/std/future/index.html) and [task](https://doc.rust-lang.org/std/task/index.html)
116    - [futures-rs](https://github.com/rust-lang/futures-rs)
117
118
119
120*/
121
122pub fn b_futures_simple_intro() {}
123
124/**
125
126    通过实现一个简单的 async/await echo server 来理解 Futures
127
128    代码示例参见本仓库内:async-echo-server
129
130    通过代码实现 简单的异步运行时(executor+reactor)
131
132*/
133
134pub fn c_async_await_echo() {}
135
136/**
137
138    # 深入理解 Future 和 Futures-rs
139
140
141    回顾 Rust 异步 task 模型
142
143    ```text
144        +------------------------------------------------------------------+
145        |                                                                  |
146        |    +--------------------------------------------------------+    |
147        |    |                                                        |    |
148        |    |   +-------------------------------------------------+  |    |
149        |    |   |-------------+ +----------+ +--------------+     |  |    |
150        |    |   || futureobj  | | futureobj| |  futureobj   |     |  |    |
151        |    |   +-------------+ +----------+ +--------------+     |  |    |
152        |    |   | 协 程  task                                      |  |    |
153        |    |   +-------------------------------------------------+  |    |
154        |    |                                                        |    |
155        |    | 线 程                                                   |    |
156        |    +--------------------------------------------------------+    |
157        |                                                                  |
158        |                                                                  |
159        |    +--------------------------------------------------------+    |
160        |    |  +--------------------------------------------------+  |    |
161        |    |  |                                                  |  |    |
162        |    |  |   +------------+ +-------------------------------+  |    |
163        |    |  |   | futureobj  | |  futureobj      || futureobj ||  |    |
164        |    |  |   +------------+ +-------------------------------+  |    |
165        |    |  |  协 程 task                                      |  |    |
166        |    |  +--------------------------------------------------+  |    |
167        |    | 线 程                                                   |    |
168        |    +--------------------------------------------------------+    |
169        |                                                                  |
170        | 进  程                                                            |
171        +------------------------------------------------------------------+
172
173
174    ```
175
176
177    1. 理解 leaf-futures vs Non-leaf-futures (async/await)
178    2. 理解 Waker:
179
180    > 当事件源注册该Future将在某个事件上等待时,它必须存储唤醒程序,以便以后可以调用唤醒来开始唤醒阶段。
181    > 为了引入并发性,能够同时等待多个事件非常重要,因此唤醒器不可能由单个事件源唯一拥有。 结果,Waker类型需要是实现 Clone 的。
182
183    - [https://doc.rust-lang.org/std/task/struct.Waker.html](https://doc.rust-lang.org/std/task/struct.Waker.html)
184
185
186    3. 理解并发(waker 并发 和 poll 并发)
187
188
189    深入 Futures-rs:
190
191    - [Future](https://doc.rust-lang.org/std/future/index.html) and [task](https://doc.rust-lang.org/std/task/index.html)
192    - [futures-rs](https://github.com/rust-lang/futures-rs)
193    - [futures-lite](https://github.com/smol-rs/futures-lite)
194
195
196*/
197
198pub fn d_futures_rs() {}
199
200/**
201
202
203    # 异步实现细节:生成器 与 协程
204
205    ## 历史
206
207    处理异步事件的三种方式:
208    - Callback
209    - Promise/Future
210    - async/await
211
212    async/await 是目前体验最好的方式,Rust 要支持它并不容易。
213
214    ## async/await 语法介绍
215
216    参考:[Asynchronous Programming in Rust](https://rust-lang.github.io/async-book/01_getting_started/01_chapter.html)
217
218    `async` 两种用法:`async fn ` 函数 和 `async {}` 块。
219
220    ```rust
221    // async 函数,真正会返回 `Future<Output = u8>`,而不是表面看上去的 `u8`
222    async fn foo() -> u8 { 5 }
223
224    // async 块用法,返回 `impl Future<Output = u8>`
225    fn bar() -> impl Future<Output = u8> {
226        // 这里 `async` 块返回  `impl Future<Output = u8>`
227        async {
228            let x: u8 = foo().await;
229            x + 5
230        }
231    }
232    ```
233
234    `await` 将暂停当前函数的执行,直到执行者将 Future 结束为止。这为其他 Future 任务提供了计算的机会。
235
236
237    ## 生成器
238
239    Future 底层实现依赖于 生成器。 `async/await` 对应底层生成器 `resume/yield` 。
240
241    ```rust
242    #![feature(generators, generator_trait)]
243    use std::ops::Generator;
244    use std::pin::Pin;
245
246    fn main() {
247        let mut gen = || {
248            yield 1;
249            yield 2;
250            yield 3;
251            return 4;
252        };
253        // for _ in 0..4 {
254        //     // 为了给嵌入式支持异步,多传入了一个空的unit给resume方法
255        //     let c = Pin::new(&mut gen).resume(());
256        //     println!("{:?}", c);
257        // }
258
259
260        let c = Pin::new(&mut gen).resume(());
261        println!("{:?}", c);
262        let c = Pin::new(&mut gen).resume(());
263        println!("{:?}", c);
264        let c = Pin::new(&mut gen).resume(());
265        println!("{:?}", c);
266        let c = Pin::new(&mut gen).resume(());
267        println!("{:?}", c);
268    }
269
270    ```
271
272    生成等价代码:
273
274    ```rust
275    #![allow(unused)]
276    #![feature(generators, generator_trait)]
277    use std::ops::{Generator, GeneratorState};
278    use std::pin::Pin;
279
280    enum __Gen {
281        // (0) 初始状态
282        Start,
283        // (1) resume方法执行以后
284        State1(State1),
285        // (2) resume方法执行以后
286        State2(State2),
287        // (3) resume方法执行以后
288        State3(State3),
289        // (4) resume方法执行以后,正好完成
290        Done
291    }
292
293
294    struct State1 { x: u64 }
295    struct State2 { x: u64 }
296    struct State3 { x: u64 }
297
298    impl Generator for __Gen {
299        type Yield = u64;
300        type Return = u64;
301
302        fn resume(self: Pin<&mut Self>, _: ()) -> GeneratorState<u64, u64> {
303            let mut_ref = self.get_mut();
304            match std::mem::replace(mut_ref, __Gen::Done) {
305                __Gen::Start => {
306                    *mut_ref = __Gen::State1(State1{x: 1});
307                    GeneratorState::Yielded(1)
308                }
309                __Gen::State1(State1{x: 1}) => {
310                    *mut_ref  = __Gen::State2(State2{x: 2});
311                    GeneratorState::Yielded(2)
312            }
313                __Gen::State2(State2{x: 2}) => {
314                    *mut_ref = __Gen::State3(State3{x: 3});
315                    GeneratorState::Yielded(3)
316                }
317                __Gen::State3(State3{x: 3}) => {
318                    *mut_ref  = __Gen::Done;
319                    GeneratorState::Complete(4)
320                }
321                _ => {
322                    panic!("generator resumed after completion")
323                }
324            }
325        }
326    }
327
328    fn main(){
329        let mut gen = {
330            __Gen::Start
331        };
332
333        for _ in 0..4 {
334            println!("{:?}", unsafe{ Pin::new(&mut gen).resume(())});
335        }
336    }
337    ```
338
339    生成器基本用法:
340
341    ```rust
342
343    #![allow(unused)]
344    #![feature(generators, generator_trait)]
345    use std::pin::Pin;
346
347    use std::ops::Generator;
348
349    pub fn up_to(limit: u64) -> impl Generator<Yield = u64, Return = u64> {
350        move || {
351            for x in 0..limit {
352                yield x;
353            }
354            return limit;
355        }
356    }
357    fn main(){
358        let a = 10;
359        let mut b = up_to(a);
360        unsafe {
361            for _ in 0..=10{
362                let c = Pin::new(&mut b).resume(());
363                println!("{:?}", c);
364            }
365        }
366    }
367
368    ```
369
370    生成器变身为迭代器:
371
372    ```rust
373    #![allow(unused)]
374    #![feature(generators, generator_trait)]
375    use std::pin::Pin;
376
377    use std::ops::{Generator, GeneratorState};
378
379    pub fn up_to() -> impl Generator<Yield = u64, Return = ()> {
380        move || {
381            let mut x = 0;
382            loop {
383                x += 1;
384                yield x;
385            }
386            return ();
387        }
388    }
389    fn main(){
390        let mut gen = up_to();
391        unsafe {
392        for _ in 0..10{
393            match Pin::new(&mut gen).resume(()) {
394                GeneratorState::Yielded(i) => println!("{:?}", i),
395                _ => println!("Completed"),
396            }
397        }
398        }
399    }
400    ```
401
402    生成器变身为 Future:
403
404    ```rust
405
406    #![allow(unused)]
407    #![feature(generators, generator_trait)]
408
409    use std::ops::{Generator, GeneratorState};
410    use std::pin::Pin;
411
412    pub fn up_to(limit: u64) -> impl Generator<Yield = (), Return = Result<u64, ()>> {
413        move || {
414            for x in 0..limit {
415                yield ();
416            }
417            return Ok(limit);
418        }
419    }
420    fn main(){
421        let limit = 2;
422        let mut gen = up_to(limit);
423        unsafe {
424        for i in 0..=limit{
425            match Pin::new(&mut gen).resume(()) {
426                GeneratorState::Yielded(v) => println!("resume {:?} : Pending", i),
427                GeneratorState::Complete(v) => println!("resume {:?} : Ready", i),
428            }
429        }
430        }
431    }
432    ```
433
434
435    跨 yield 借用会报错:
436
437    ```rust
438    #![allow(unused)]
439    #![feature(generators, generator_trait)]
440
441    use std::ops::Generator;
442    use std::pin::Pin;
443
444    pub fn up_to(limit: u64) -> impl Generator<Yield = u64, Return = u64> {
445        move || {
446            let a = 5;
447            let ref_a = &a;
448            for x in 0..limit {
449                yield x;
450                if x == 5{
451                    yield *ref_a;
452                }
453            }
454            return limit;
455        }
456    }
457    fn main(){
458        let a = 10;
459        let mut b = up_to(a);
460        unsafe {
461            for _ in 0..=10{
462                let c = Pin::new(&mut b).resume(());
463                println!("{:?}", c);
464            }
465        }
466    }
467    ```
468
469
470    自引用结构:
471
472    ```rust
473    #![feature(generators, generator_trait)]
474    use std::ops::Generator;
475    use std::pin::Pin;
476    fn main(){
477        let mut generator = move || {
478            let to_borrow = String::from("Hello");
479            let borrowed = &to_borrow;
480            // error[E0626]: borrow may still be in use when generator yields
481            yield borrowed.len();
482            println!("{} world!", borrowed);
483        };
484    }
485
486    ```
487
488    模拟底层实现 generator :
489
490    ```rust
491    #![allow(unused)]
492    #![feature(never_type)] // Force nightly compiler to be used in playground
493    // by betting on it's true that this type is named after it's stabilization date...
494    pub fn main() {
495        let mut gen = GeneratorA::start();
496        let mut gen2 = GeneratorA::start();
497
498        if let GeneratorState::Yielded(n) = gen.resume() {
499            println!("Got value {}", n);
500        }
501
502        // std::mem::swap(&mut gen, &mut gen2); // <--- Big problem!
503
504        if let GeneratorState::Yielded(n) = gen2.resume() {
505            println!("Got value {}", n);
506        }
507
508        // This would now start gen2 since we swapped them.
509        if let GeneratorState::Complete(()) = gen.resume() {
510            ()
511        };
512
513        if let GeneratorState::Complete(()) = gen2.resume() {
514            ()
515        };
516    }
517    enum GeneratorState<Y, R> {
518        Yielded(Y),
519        Complete(R),
520    }
521
522    trait Generator {
523        type Yield;
524        type Return;
525        fn resume(&mut self) -> GeneratorState<Self::Yield, Self::Return>;
526    }
527
528    enum GeneratorA {
529        Enter,
530        Yield1 {
531            to_borrow: String,
532            borrowed: *const String,
533        },
534        Exit,
535    }
536
537    impl GeneratorA {
538        fn start() -> Self {
539            GeneratorA::Enter
540        }
541    }
542    impl Generator for GeneratorA {
543        type Yield = usize;
544        type Return = ();
545        fn resume(&mut self) -> GeneratorState<Self::Yield, Self::Return> {
546                match self {
547                GeneratorA::Enter => {
548                    let to_borrow = String::from("Hello");
549                    let borrowed = &to_borrow;
550                    let res = borrowed.len();
551                    *self = GeneratorA::Yield1 {to_borrow, borrowed: std::ptr::null()};
552
553                    // We set the self-reference here
554                    if let GeneratorA::Yield1 {to_borrow, borrowed} = self {
555                        *borrowed = to_borrow;
556                    }
557
558                    GeneratorState::Yielded(res)
559                }
560
561                GeneratorA::Yield1 {borrowed, ..} => {
562                    let borrowed: &String = unsafe {&**borrowed};
563                    println!("{} world", borrowed);
564                    *self = GeneratorA::Exit;
565                    GeneratorState::Complete(())
566                }
567                GeneratorA::Exit => panic!("Can't advance an exited generator!"),
568            }
569        }
570    }
571    ```
572    上面代码在 Safe Rust 下是存在问题的,有 UB 风险。
573
574
575    用 Pin 修正:
576
577    ```rust
578    #![feature(generators, generator_trait)]
579    use std::ops::{Generator, GeneratorState};
580
581
582    pub fn main() {
583        // 使用 static 关键字创建 immovable 生成器
584        let gen1 = static || {
585            let to_borrow = String::from("Hello");
586            let borrowed = &to_borrow;
587            yield borrowed.len();
588            println!("{} world!", borrowed);
589        };
590
591        let gen2 = static || {
592            let to_borrow = String::from("Hello");
593            let borrowed = &to_borrow;
594            yield borrowed.len();
595            println!("{} world!", borrowed);
596        };
597
598        let mut pinned1 = Box::pin(gen1);
599        let mut pinned2 = Box::pin(gen2);
600
601        if let GeneratorState::Yielded(n) = pinned1.as_mut().resume(()) {
602            println!("Gen1 got value {}", n);
603        }
604
605        if let GeneratorState::Yielded(n) = pinned2.as_mut().resume(()) {
606            println!("Gen2 got value {}", n);
607        };
608
609        let _ = pinned1.as_mut().resume(());
610        let _ = pinned2.as_mut().resume(());
611    }
612
613    ```
614
615
616    第三方库 genawaiter:stable rust 实现 generator 。
617
618    [https://github.com/whatisaphone/genawaiter](https://github.com/whatisaphone/genawaiter)
619
620*/
621pub fn e_generator() {}
622
623/**
624
625
626    ### 前奏
627
628
629    Safe Rust 无法构建自引用结构体:
630
631    ```rust
632    struct SelfReferential<'a> {
633        a: String,
634        b: &'a String,
635    }
636
637    fn main() {
638        let a = String::from("Hello");
639        let _sr = SelfReferential { a, b: &a }; // error: borrow of moved value: `a`
640    }
641    ```
642
643   另一个示例:即便使用 `Box<T>` 放到堆上,也存在风险:
644
645    ```rust
646    struct SelfReferential {
647        self_ptr: *const Self,
648    }
649
650    fn main() {
651        let mut heap_value = Box::new(SelfReferential {
652            self_ptr: 0 as *const _,
653        });
654        let ptr = &*heap_value as *const SelfReferential;
655        heap_value.self_ptr = ptr;
656        println!("heap value at: {:p}", heap_value);
657        println!("internal reference: {:p}", heap_value.self_ptr);
658
659        // 风险代码
660        let stack_value = mem::replace(&mut *heap_value, SelfReferential {
661            self_ptr: 0 as *const _,
662            _pin: PhantomPinned,
663        });
664        println!("value at: {:p}", &stack_value);
665        println!("internal reference: {:p}", stack_value.self_ptr);
666    }
667
668    ```
669
670
671    使用指针来构建,但是有安全风险:
672
673    ```rust
674    #[derive(Debug)]
675    struct SelfReferential {
676        a: String,
677        b: *const String,
678    }
679
680    impl SelfReferential {
681        fn new(txt: &str) -> Self {
682            Self {
683                a: String::from(txt),
684                b: std::ptr::null(),
685            }
686        }
687
688        fn init(&mut self) {
689            let self_ref: *const String = &self.a;
690            self.b = self_ref;
691        }
692
693        fn a(&self) -> &str {
694            &self.a
695        }
696
697        fn b(&self) -> &String {
698            unsafe {&*(self.b)}
699        }
700    }
701
702    fn main() {
703        let mut sf1 = SelfReferential::new("test1");
704        sf1.init();
705        let mut sf2 = SelfReferential::new("test2");
706        sf2.init();
707
708        println!("a: {}, b: {}", sf1.a(), sf1.b());
709        println!("a: {:p}, b: {:p}, t: {:p}", &(sf1.a), sf1.b, &(sf2.a));
710        // 使用swap()函数交换两者,这里发生了move
711        std::mem::swap(&mut sf1, &mut sf2);
712
713
714        sf1.a = "I've totally changed now!".to_string();
715        println!("a: {}, b: {}", sf2.a(), sf2.b());
716        println!("a: {:p}, b: {:p}, t: {:p}", &(sf1.a), sf1.b, &(sf2.a) ) ;
717    }
718    ```
719
720    Pin 到栈上:
721
722    ```rust
723    use std::pin::Pin;
724    use std::marker::PhantomPinned;
725
726    #[derive(Debug)]
727    struct SelfReferential {
728        a: String,
729        b: *const String,
730        _marker: PhantomPinned,
731    }
732
733    impl SelfReferential {
734        fn new(txt: &str) -> Self {
735            Self {
736                a: String::from(txt),
737                b: std::ptr::null(),
738                _marker: PhantomPinned, // This makes our type `!Unpin`
739            }
740        }
741
742        fn init<'a>(self: Pin<&'a mut Self>) {
743            let self_ptr: *const String = &self.a;
744            let this = unsafe { self.get_unchecked_mut() };
745            this.b = self_ptr;
746        }
747
748        fn a<'a>(self: Pin<&'a Self>) -> &'a str {
749            &self.get_ref().a
750        }
751
752        fn b<'a>(self: Pin<&'a Self>) -> &'a String {
753            unsafe { &*(self.b) }
754        }
755    }
756
757    pub fn main() {
758        let mut sf1 = unsafe { Pin::new_unchecked(&mut SelfReferential::new("test1")) };
759        SelfReferential::init(sf1.as_mut());
760
761        let mut sf2 = unsafe { Pin::new_unchecked(&mut SelfReferential::new("test2")) };
762        SelfReferential::init(sf2.as_mut());
763
764        println!("a: {}, b: {}", SelfReferential::a(sf1.as_ref()), SelfReferential::b(sf1.as_ref()));
765        std::mem::swap(sf1.get_mut(), sf2.get_mut());
766        println!("a: {}, b: {}", SelfReferential::a(sf2.as_ref()), SelfReferential::b(sf2.as_ref()));
767    }
768
769    ```
770
771    一个 `Pin<&mut T>` 必须在被引用的T的整个生命周期被保持 pinned,这对于栈上的变量很难确认。
772    为了帮助处理这类问题,就有了像[pin-utils](https://docs.rs/pin-utils)这样的 crate。
773
774
775    栈上 vs 堆上:
776
777    ```rust
778    fn main(){
779
780        let s = "hello".to_string();
781        let p = s.as_str();
782        println!("{:p}", p);
783        println!("{:p}", s.as_ptr());
784        println!("{:p}", &s);
785    }
786    ```
787
788
789    Pin 到 堆上:
790
791    ```rust
792    use std::pin::Pin;
793    use std::marker::PhantomPinned;
794
795    #[derive(Debug)]
796    struct SelfReferential {
797        a: String,
798        b: *const String,
799        _marker: PhantomPinned,
800    }
801
802    impl SelfReferential {
803        fn new(txt: &str) -> Pin<Box<Self>> {
804            let t = Self {
805                a: String::from(txt),
806                b: std::ptr::null(),
807                _marker: PhantomPinned,
808            };
809            let mut boxed = Box::pin(t);
810            let self_ptr: *const String = &boxed.as_ref().a;
811            unsafe { boxed.as_mut().get_unchecked_mut().b = self_ptr };
812
813            boxed
814        }
815
816        fn a<'a>(self: Pin<&'a Self>) -> &'a str {
817            &self.get_ref().a
818        }
819
820        fn b<'a>(self: Pin<&'a Self>) -> &'a String {
821            unsafe { &*(self.b) }
822        }
823    }
824
825    pub fn main() {
826        let mut sf1 = SelfReferential::new("test1");
827        let mut sf2 = SelfReferential::new("test2");
828
829        println!("a: {}, b: {}",sf1.as_ref().a(), sf1.as_ref().b());
830        std::mem::swap(sf1.get_mut(), sf1.get_mut());
831        // std::mem::swap(&mut *sf1, &mut *sf2);
832        println!("a: {}, b: {}",sf2.as_ref().a(), sf2.as_ref().b());
833    }
834
835    ```
836
837    另外一个示例:
838
839    ```rust
840    use std::mem;
841    use std::marker::PhantomPinned;
842    use std::pin::Pin;
843
844    struct SelfReferential {
845        self_ptr: *const Self,
846        _pin: PhantomPinned,
847    }
848
849    fn main() {
850        let mut heap_value = Box::pin(SelfReferential {
851            self_ptr: 0 as *const _,
852            _pin: PhantomPinned,
853        });
854        let ptr = &*heap_value as *const SelfReferential;
855
856        // 这是安全的,因为修改结构体字段不会让结构体发生move
857        unsafe {
858            let mut_ref = Pin::as_mut(&mut heap_value);
859            Pin::get_unchecked_mut(mut_ref).self_ptr = ptr;
860        }
861
862        println!("heap value at: {:p}", heap_value);
863        println!("internal reference: {:p}", heap_value.self_ptr);
864
865        // 有效阻止了下面风险代码的发生
866
867        let stack_value = mem::replace(&mut *heap_value, SelfReferential {
868            self_ptr: 0 as *const _,
869            _pin: PhantomPinned,
870        });
871        println!("value at: {:p}", &stack_value);
872        println!("internal reference: {:p}", stack_value.self_ptr);
873    }
874
875
876
877
878    ```
879
880    ### 异步实现细节:Pin 与 UnPin
881
882    async/await 的要支持引用,就必须支持自引用结构。
883
884    Rust 源码内部:[https://github.com/rust-lang/rust/blob/master/library/core/src/future/mod.rs](https://github.com/rust-lang/rust/blob/master/library/core/src/future/mod.rs)
885
886    ```rust
887    // From Generator to Future
888    pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
889    where
890        T: Generator<ResumeTy, Yield = ()>,
891    {
892        #[rustc_diagnostic_item = "gen_future"]
893        struct GenFuture<T: Generator<ResumeTy, Yield = ()>>(T);
894
895        // 依赖这样一个重要事实:
896        // 即 async/await Future 是不可移动的,以便在基础生成器中创建自引用借用。
897        impl<T: Generator<ResumeTy, Yield = ()>> !Unpin for GenFuture<T> {}
898
899        impl<T: Generator<ResumeTy, Yield = ()>> Future for GenFuture<T> {
900            type Output = T::Return;
901            fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
902                // SAFETY: Safe because we're !Unpin + !Drop, and this is just a field projection.
903                let gen = unsafe { Pin::map_unchecked_mut(self, |s| &mut s.0) };
904
905                // Resume the generator, turning the `&mut Context` into a `NonNull` raw pointer. The
906                // `.await` lowering will safely cast that back to a `&mut Context`.
907                // resume 里传递上下文指针
908                match gen.resume(ResumeTy(NonNull::from(cx).cast::<Context<'static>>())) {
909                    GeneratorState::Yielded(()) => Poll::Pending,
910                    GeneratorState::Complete(x) => Poll::Ready(x),
911                }
912            }
913        }
914
915        GenFuture(gen)
916    }
917
918    ```
919
920    Pin 利用类型系统避免 `&mut T` 被拿到,达到 固定 引用/指针 的目的。
921
922    [https://doc.rust-lang.org/std/pin/index.html](https://doc.rust-lang.org/std/pin/index.html)
923
924    - [pin-project-lite](https://crates.io/crates/pin-project-lite)
925
926
927    ### Pin 与 Unpin 属性
928
929    来自:[Asynchronous Programming in Rust](https://rust-lang.github.io/async-book/04_pinning/01_chapter.html)
930
931    - 如果 `T: Unpin`(默认会实现),那么 `Pin<'a, T>` 完全等价于 `&'a mut T`。换言之: `Unpin` 意味着这个类型被移走也没关系,就算已经被固定了,所以 `Pin` 对这样的类型毫无影响。
932
933    - 如果 `T: !Unpin`, 获取已经被固定的 `T` 类型示例的 `&mut T`需要 `unsafe`。
934
935    - 标准库中的大部分类型实现 `Unpin`,在 Rust 中遇到的多数普通类型也是一样。但是, `async/await` 生成的 `Future` 是个例外。
936
937    - 你可以在 nightly 通过特性标记来给类型添加 `!Unpin` 约束,或者在 stable 给你的类型加 `std::marker::PhatomPinned` 字段。
938
939    - 你可以将数据固定到栈上或堆上
940
941    - 固定 `!Unpin` 对象到栈上需要 `unsafe`
942
943    - 固定 `!Unpin` 对象到堆上不需要` unsafe`。`Box::pin`可以快速完成这种固定。
944
945    - 对于 `T: !Unpin` 的被固定数据,你必须维护好数据内存不会无效的约定,或者叫 固定时起直到释放。这是 固定约定 中的重要部分。
946
947
948    ### Pin 用法约定
949
950    -  带 Pin 结构化包装的  投影 (`structural Pin projection`) :  `Pin<&mut Wrapper<Field>> -> Pin<&mut Field>`。 `pin_utils::unsafe_pinned!` 宏可以做。
951        - 当结构体所有的字段都实现 Unpin ,整个结构体才可以实现 Unpin。(不允许任何实现使用不安全的方式将此类字段移出,比如 `Option::take` 是被禁止的)
952        - 结构体不能用 `#[repr(packed)]`
953        - 如果`Drop::drop`不移动任何字段,则整个结构只能实现`Drop`
954    -  不带 Pin 结构化包装的  投影 (`no structural Pin projection`) :  `Pin<&mut Wrapper<Field>> -> &mut Field`。 ` pin_utils::unsafe_unpinned! ` 宏可以做的。
955
956    参考: [futures-util::future::map](https://github.com/rust-lang/futures-rs/blob/0.3.0-alpha.15/futures-util/src/future/map.rs#L14)
957
958    ```rust
959    impl<Fut, F> Map<Fut, F> {
960        unsafe_pinned!(future: Fut); // pin projection -----+
961        unsafe_unpinned!(f: Option<F>); // not pinned --+   |
962    //                                                  |   |
963    //                 ...                              |   |
964    //                                                  |   |
965        fn poll (mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
966            //                                          |   |
967            match self.as_mut().future().poll(cx) { // <----+ required here
968                Poll::Pending => Poll::Pending, //      |
969                Poll::Ready(output) => { //             |
970                    let f = self.f().take() // <--------+ allows this
971
972    ```
973
974*/
975pub fn f_pin_unpin() {}
976
977/**
978
979    # `no-std` 下的异步
980
981    - [futures-micro](https://github.com/irrustible/futures-micro)
982    - [embassy](https://github.com/embassy-rs/embassy)
983    - [executor for no-std](https://github.com/richardanaya/executor)
984
985*/
986pub fn no_std_async() {}
987
988/**
989    # 一个异步缓存代码实现源码导读 :[retainer](https://github.com/ChaosStudyGroup/retainer)
990
991*/
992pub fn async_cache_demo() {}