githubdns
githubdns copied to clipboard
为什么在我本机跑是顺序执行的呢
你如何证明是顺序执行的?
我是照着你写的思路写了一个,刚接触rust不久,可能有误解,麻烦大神帮我看看`use std::time::Duration;
use futures::future::join_all;
#[tokio::main] async fn main() { let mut v = Vec::new(); for _ in 1..10 { v.push(async move { println!("start {:?}", std::thread::current()); std::thread::sleep(Duration::from_millis(500)); }); }; join_all(v).await; } `
我这个版本是每隔0.5秒打印一个,并且线程都是主线程,是哪个姿势不正确吗
语法高亮一下,排版一下吧
use std::time::Duration;
use futures::future::join_all;
#[tokio::main]
async fn main() {
let mut v = Vec::new();
for _ in 1..10 {
v.push(async move {
println!("start {:?}", std::thread::current());
std::thread::sleep(Duration::from_millis(500));
});
};
join_all(v).await;
}
impl<F> Future for JoinAll<F>
where
F: Future,
{
type Output = Vec<F::Output>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut all_done = true;
for mut elem in iter_pin_mut(self.elems.as_mut()) {
if let Some(pending) = elem.as_mut().pending_pin_mut() {
if let Poll::Ready(output) = pending.poll(cx) {
elem.set(ElemState::Done(Some(output)));
} else {
all_done = false;
}
}
}
if all_done {
let mut elems = mem::replace(&mut self.elems, Box::pin([]));
let result = iter_pin_mut(elems.as_mut())
.map(|e| e.take_done().unwrap())
.collect();
Poll::Ready(result)
} else {
Poll::Pending
}
}
}
/// Future for the [`join_all`] function.
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct JoinAll<F>
where
F: Future,
{
elems: Pin<Box<[ElemState<F>]>>,
}
你期待什么样的输入,什么样的输出呢
期待程序能够并发执行,几乎同时打印10行,然后停留0.5秒结束主线程
那你别用std::thread::sleep啊,你用tokio提供的delay, 你把执行任务的线程阻塞了,他怎么执行其他task呢?
tokio runtime 不会主动开多个线程吗
https://stevenbai.top/rust/futures_explained_in_200_lines_of_rust/ 可以看一下我的这个博客,看看背后的机制是什么, 简单来说:
if let Poll::Ready(output) = pending.poll(cx) {
elem.set(ElemState::Done(Some(output)));
这两行中的pending.poll,调用的就是你的
async move {
println!("start {:?}", std::thread::current());
std::thread::sleep(Duration::from_millis(500));
}
这个async,sleep 500ms才会返回。
好的,谢谢,那篇文章得有时间多看几遍才能整明白,昨天晚上尝试了一下,被第二个例子劝退了,哈哈