当前没有任务在运行

时间:2019-10-03 21:28:23

标签: rust

我遇到错误:no Task is currently running,当我尝试使用UnboundedSenderUnboundedReceiver而不使用tokio::run()时。

这是错误:

Press Ctrl-C to abort
thread 'receiver thread' panicked at 'no Task is currently running', src/libcore/option.rs:1166:5
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/libunwind.rs:88
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:47
   3: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:36
   4: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:200
   5: std::panicking::default_hook
             at src/libstd/panicking.rs:214
   6: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:477
   7: std::panicking::continue_panic_fmt
             at src/libstd/panicking.rs:384
   8: rust_begin_unwind
             at src/libstd/panicking.rs:311
   9: core::panicking::panic_fmt
             at src/libcore/panicking.rs:85
  10: core::option::expect_failed
             at src/libcore/option.rs:1166
  11: core::option::Option<T>::expect
             at /rustc/dddb7fca09dc817ba275602b950bb81a9032fb6d/src/libcore/option.rs:345
  12: futures::task_impl::with
             at /home/nickhash/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-0.1.29/src/task_impl/mod.rs:46
  13: futures::task_impl::current
             at /home/nickhash/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-0.1.29/src/task_impl/mod.rs:118
  14: futures::sync::mpsc::Receiver<T>::try_park
             at /home/nickhash/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-0.1.29/src/sync/mpsc/mod.rs:902
  15: <futures::sync::mpsc::Receiver<T> as futures::stream::Stream>::poll
             at /home/nickhash/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-0.1.29/src/sync/mpsc/mod.rs:936
  16: <futures::sync::mpsc::UnboundedReceiver<T> as futures::stream::Stream>::poll
             at /home/nickhash/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-0.1.29/src/sync/mpsc/mod.rs:1004
  17: fut2::launch_receiver_thread::{{closure}}
             at src/main.rs:16
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
^C

我正在运行的代码是:

use std:: {thread,time::Duration};
use futures::stream::*;
use futures::prelude::*;


fn launch_sender_thread(tx: futures::sync::mpsc::UnboundedSender<()>) {
    let _ = thread::Builder::new().name("sender thread".to_string()).spawn(move || {
        loop {
            tx.clone().send(());
            thread::sleep(Duration::from_millis(3000));
        }   
    });
}
fn launch_receiver_thread(mut rx: futures::sync::mpsc::UnboundedReceiver<()>) {
    let _ = thread::Builder::new().name("receiver thread".to_string()).spawn(move || {
        match rx.poll() {
            Ok(Async::Ready(Some(_))) => {
                println!("thread2: received data");
            },  
            Ok(_) => (), 
            Err(err) => {
                println!("poll err {:?}",err);
            },
        } 
        thread::sleep(Duration::from_millis(1000));
    });
}

fn main() {

    let (sender, receiver) = futures::sync::mpsc::unbounded::<()>();
    launch_receiver_thread(receiver);
    launch_sender_thread(sender);
    println!("Press Ctrl-C to abort");
    thread::sleep(Duration::from_millis(10000000));        
}

因此,基本上我想从一个线程向另一个线程发送和接收数据,但是不使用Future对象,这可能吗? 如果不可能,那么如何通过最少使用Future crate来解决此错误?要求使用futures::sync::mpsc::UnboundedSenderfutures::sync::mpsc::UnboundedSender进行通信。

Cargo.toml:

[package]
name = "fut2"
version = "0.1.0"
edition = "2018"

[dependencies]
futures = { version = "0.1" }

1 个答案:

答案 0 :(得分:2)

  

但不使用Future对象,这可能吗?

可以使用UnboundedSenderUnboundedSender来与期货板条箱进行最小程度的交互,但是必须将期货与任务一起使用。但是,这不完全是您的错;期货文档和API设计对此并不十分清楚。在0.2的化身中,将有一个task context显式地通过各种API调用进行线程化。例如,0.1.x中的Stream::poll被定义为:

fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error>

0.2.x中,它是Stream::poll_next

fn poll_next(
    &mut self, 
    cx: &mut Context
) -> Result<Async<Option<Self::Item>>, Self::Error>

因此,您将无法在任务外部进行相同的错误轮询。

直到0.1.x期货板条箱都可以使用:

use futures::sync::mpsc::{UnboundedReceiver, UnboundedSender};
use std::thread::{self, JoinHandle};

fn launch_sender_thread(tx: UnboundedSender<()>) -> JoinHandle<()> {
    thread::Builder::new()
        .name("sender thread".to_string())
        .spawn(move || loop {
            let _ = tx.unbounded_send(());
        })
        .unwrap()
}

fn launch_receiver_thread(rx: UnboundedReceiver<()>) -> JoinHandle<()> {
    thread::Builder::new()
        .name("receiver thread".to_string())
        .spawn(move || {
            let mut task = futures::executor::spawn(rx);
            match task.wait_stream() {
                Some(Ok(_)) => println!("thread2: received data"),
                Some(Err(e)) => println!("poll err {:?}", e),
                None => (),
            }
        })
        .unwrap()
}

fn main() {
    let (sender, receiver) = futures::sync::mpsc::unbounded::<()>();
    let recv = launch_receiver_thread(receiver);
    let send = launch_sender_thread(sender);

    println!("Press Ctrl-C to abort");
    recv.join().unwrap();
    send.join().unwrap();
}

注意,您也可以通过任务来驱动tx。在这里调用unbounded_send更加简单。