0

我根据本教程编写了一个简单的未来,如下所示:

extern crate chrono; // 0.4.6
extern crate futures; // 0.1.25

use std::{io, thread};
use chrono::{DateTime, Duration, Utc};
use futures::{Async, Future, Poll, task};

pub struct WaitInAnotherThread {
    end_time: DateTime<Utc>,
    running: bool,
}

impl WaitInAnotherThread {
    pub fn new(how_long: Duration) -> WaitInAnotherThread {
        WaitInAnotherThread {
            end_time: Utc::now() + how_long,
            running: false,
        }
    }

    pub fn run(&mut self, task: task::Task) {
        let lend = self.end_time;

        thread::spawn(move || {
            while Utc::now() < lend {
                let delta_sec = lend.timestamp() - Utc::now().timestamp();
                if delta_sec > 0 {
                    thread::sleep(::std::time::Duration::from_secs(delta_sec as u64));
                }
                task.notify();
            }
            println!("the time has come == {:?}!", lend);
        });
    }
}

impl Future for WaitInAnotherThread {
    type Item = ();
    type Error = Box<io::Error>;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        if Utc::now() < self.end_time {
            println!("not ready yet! parking the task.");

            if !self.running {
                println!("side thread not running! starting now!");
                self.run(task::current());
                self.running = true;
            }

            Ok(Async::NotReady)
        } else {
            println!("ready! the task will complete.");
            Ok(Async::Ready(()))
        }
    }
}

所以问题是我如何pub fn run(&mut self, task: task::Task)用不会创建新线程以供将来解决的东西替换。如果有人可以在run没有单独线程的情况下用替换函数重写我的代码,这将有助于我理解事情应该如何。我也知道tokio有一个超时实现,但我需要这个代码来学习。

4

1 回答 1

0

我想我明白你的意思。假设您有两个任务,即 Main 和 Worker1,在这种情况下,您正在轮询 worker1 以等待答案;但是还有更好的办法,那就是等待Worker1的竞争;这可以在没有任何 Future 的情况下完成,您只需从 Main 调用 Worker1 函数,当 worker 结束时 Main 将继续。您不需要未来,您只是在调用一个函数,而 Main 和 Worker1 的划分只是过于复杂了。

现在,我认为您的问题在您添加至少另一个工人,最后添加 Worker2 的那一刻变得相关,并且您希望 Main 在两个任务之一完成后立即恢复计算;并且您不希望这些任务在另一个线程/进程中执行,可能是因为您正在使用异步调用(这只是意味着线程在其他地方完成,或者您的级别足够低以至于您收到硬件中断)。

由于您的 Worker1 和 Worker2 必须共享同一个线程,因此您需要一种方法来保存当前执行 Main,为其中一个 worker 创建一个,并在经过一定数量的工作、时间或其他(调度程序)之后,切换到另一个工人,依此类推。这是一个多任务系统,在 Rust 中有各种软件实现;但是有了硬件支持,你可以做一些只有软件才能做的事情(比如让硬件阻止一个任务从另一个任务访问资源),另外你可以让 CPU 负责任务切换等等……嗯,这就是线程和进程。

Future 不是您要寻找的,它们是更高级别的,您可以找到一些支持它们的软件调度程序。

于 2018-11-01T14:02:12.480 回答