日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

rust異步編程詳細講解_Rust語言

作者:上后左愛 ? 更新時間: 2023-01-15 編程語言

簡化版本 Future

// wake 函數 reactor發現狀態是ready 通知executor 函數
trait SimpleFuture {
    type Output;
    fn poll(&mut self, wake: fn()) -> Poll<Self::Output>;
    // fn poll(&mut self, wake: u32) -> Poll<Self::Output>;
}
enum Poll<T> {
    Ready(T),
    Pending,
}
future 返回的是Poll枚舉 , 狀態有Ready ,pending 狀態
executor 調用 Future 任務,Ready 執行完成, pending 阻塞 執行其他任務
reactor 檢查任務是否變成 ready

simpleFuture 是一個trait, 屬于struct MySleep

use std::thread;
use std::time::Duration;
trait SimpleFuture {
    type Output;
    // fn poll(&mut self, wake: fn()) -> Poll<Self::Output>;
    fn poll(&mut self, wake: u32) -> Poll<Self::Output>;
}
enum Poll<T> {
    Ready(T),
    Pending,
}
// 自定義循環技術
struct MySleeper {
    polls: u64,
    wake: u32, // 簡化使用整數 替換函數
}
impl MySleeper {
    fn new(wake: u32) -> Self {
        MySleeper {
            polls: 0,
            wake: wake,
        }
    }
}
static mut FINISHED: bool = false;
impl SimpleFuture for MySleeper {
    type Output = ();
    fn poll(&mut self, wake: u32) -> Poll<Self::Output> {
        // 簡化編程 使用unsafe 使用外部的變量
        unsafe {
            if FINISHED {
                Poll::Ready(())
            } else {
                self.wake = wake;
                self.polls += 1;
                println!("polls = {}", self.polls);
                Poll::Pending
            }
        }
    }
}
// 定義自定義Reactor
struct MyReactor {
    wake: u32,
    // 通知exector
    handle: Option<thread::JoinHandle<()>>, // 線程句柄
}
impl MyReactor {
    fn new() -> Self {
        MyReactor {
            wake: 0,
            handle: None,
        }
    }
    // 知道哪個wake 通知具體函數
    fn add_wake(&mut self, wake: u32) {
        self.wake = wake;
    }
    // check status
    fn check_status(&mut self) {
        if self.handle.is_none() {
            let wake = self.wake;
            // 模擬 通過死循環進行監控狀態
            let handle = thread::spawn(|| loop {
                thread::sleep(Duration::from_secs(5));
                unsafe {
                    //模擬future就緒,然后調用wake
                    FINISHED = true;
                }
            });
            self.handle = Some(handle);
        }
    }
}
struct MyExecutor;
impl MyExecutor {
    fn block_on<F: SimpleFuture>(mut myfuture: F, wake: u32) {
        //阻塞執行future
        loop {
            match myfuture.poll(wake) {
                Poll::Ready(_) => {
                    println!("my future is ok");
                    break;
                }
                Poll::Pending => unsafe {
                    while !FINISHED {
                        // 循環 每隔一秒鐘檢測一下
                        thread::sleep(Duration::from_secs(1));
                    }
                }
            }
        }
    }
}
fn main() {
    let mut reactor = MyReactor::new();
    let sleeper = MySleeper::new(5);
    let wake = sleeper.wake;
    reactor.add_wake(wake);
    reactor.check_status();
    MyExecutor::block_on(sleeper, wake);
}

在簡化版本的Future 對象中 有定義MyReactor, 和 MyExecutor, MyReactor wake 函數進行標記后調用自定義的check_staus 模擬Future的就緒,調用wake 函數通知, 在MyExector 的block_on 函數中 通過wake函數匹配狀態 判讀任務是否已經Ready

理解Future的模型

運行時狀態的框架: async-std, futures 中已經實現executor不需要自己在實現。

異步編程中,rust的編程語言中只給我們提供trait Future, async-std, tokio,futures 等異步編程庫 對其進行擴展,并且提供相對應的函數

 async fn hello() {
     println!("hello");
 }
等價于下面函數
fn hello() -> impl Future<Output=()> {
    async {
        println!("hello");
    }
}

rust 標準庫中 Future如下:

 pub trait Future {
     type Output;
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
 }
// Pin 可以創建不可移動Future,通過不可移動對象在他們字段中存儲指針
struct MyFut {
	a: i32,
	ptr: *const i32, // 指針指向字段a 所在的內存首地址
}

async/awit 使用

在閉包中使用async

use std::future::Future;
fn my_function() -> impl Future<Output  = u8> {
	let closure = async |x: u8| {
		x
	};
	
	closure(5)
}
閉包在穩定版本還不支持,后續的版本中會支持 異步閉包
##### async lifetime 
```rust
這個函數的生命周期
// fn foo_expand(x: &'a u8) -> impl Future<Output = u8> + 'a {
//     async {
//         *x
//     }
// }
async fn foo(x: & u8) -> u8 {
    *x
}
// async 函數返回一個Future的對象
 fn good() -> impl Future<Output = u8>{
 // 異步代碼塊中,定義 變量后 調用foo_expand async 函數后進行await
     async {
     // x 修飾后 x 的生命周期有多長 就有多長
        let x = 5;
        foo_expand(&x).await
   }
}

原文鏈接:https://blog.csdn.net/qq_27217017/article/details/123463198

欄目分類
最近更新