高并发中Poll、Epoll、Future的概念
高并发中有几个重要概念:Poll、Epoll、Future。
Future并不是一个主流的实现,但是Future与Poll的概念又是如此重要,我们必须放在开头来讲,因此这里先将重心放在Rust身上,由于Rust与Go、Java相比对于Future实现比较完整,特性支持也彻底。因此下面的代码均以Rust为例。
简单来讲Future不是一个值,而是一种值类型,一种在未来才能得到的值类型。Future对象必须实现Rust标准库中的std::future:: future接口。Future的输出Output是Future完成后才能生成的值。在Rust中Future通过管理器调用Future::poll来推动Future的运算。Future本质上是一个状态机,而且可以嵌套使用,我们来看一下面这个例子,在main函数中,我们实例化MainFuture并调用.await,而MainFuture除了在几个状态之间迁移以外,还会调用一个Delay的Future,从而实现Future的嵌套。
MainFuture以State0状态做为初始状态。当调度器调用poll方法时,MainFuture会尝试尽可能地提升其状态。如果future完成,则返回Poll::Ready,如果MainFuture没有完成,则是由于它等待的DelayFuture没有达到Ready状态,那么此时返回Pending。调度器收到Pending结果,会将这个MainFuture重新放回待调度的队列当中,稍后会再度调用Poll方法来推进Future的执行。具体如下:
代码语言:javascript复制use std::future::Future;
use std::pin::Pin;
usestd::task::{Context, Poll};
usestd::time::{Duration, Instant};
struct Delay {
when: Instant,
}
impl Future forDelay {
type Output = &'static str;
fn poll(self: Pin<&mut Self>, cx:&mut Context<'_>)
-> Poll<&'static str>
{
if Instant::now() >= self.when {
println!("Hello world");
Poll::Ready("done")
} else {
cx.waker().wake_by_ref();
Poll::Pending
}
}
}
enum MainFuture {
State0,
State1(Delay),
Terminated,
}
impl Future forMainFuture {
type Output = ();
fn poll(mut self: Pin<&mut Self>,cx: &mut Context<'_>)
-> Poll<()>
{
use MainFuture::*;
loop {
match *self {
State0 => {
let when = Instant::now()
Duration::from_millis(1);
let future = Delay { when};
println!("initstatus");
*self = State1(future);
}
State1(ref mut my_future) =>{
matchPin::new(my_future).poll(cx) {
Poll::Ready(out) =>{
assert_eq!(out,"done");
println!("delay finished this future is ready");
*self = Terminated;
returnPoll::Ready(());
}
Poll::Pending => {
println!("notready");
returnPoll::Pending;
}
}
}
Terminated => {
panic!("future polledafter completion")
}
}
}
}
}
#[tokio::main]
async fn main() {
let when = Instant::now() Duration::from_millis(10);
let mainFuture=MainFuture::State0;
mainFuture.await;
}
以上就是高并发中Poll、Epoll、Future的概念,希望对大家有所帮助。更多精彩内容分享:头条