【发布时间】:2019-12-23 19:55:14
【问题描述】:
我正在涉足 tokio-core,并且可以弄清楚如何生成事件循环。但是有两件事我不确定 - 如何优雅地退出事件循环以及如何退出在事件循环内运行的流。例如,考虑这段简单的代码,它在事件循环中生成两个侦听器并等待另一个线程指示退出条件:
extern crate tokio_core;
extern crate futures;
use tokio_core::reactor::Core;
use futures::sync::mpsc::unbounded;
use tokio_core::net::TcpListener;
use std::net::SocketAddr;
use std::str::FromStr;
use futures::{Stream, Future};
use std::thread;
use std::time::Duration;
use std::sync::mpsc::channel;
fn main() {
let (get_tx, get_rx) = channel();
let j = thread::spawn(move || {
let mut core = Core::new().unwrap();
let (tx, rx) = unbounded();
get_tx.send(tx).unwrap(); // <<<<<<<<<<<<<<< (1)
// Listener-0
{
let l = TcpListener::bind(&SocketAddr::from_str("127.0.0.1:44444").unwrap(),
&core.handle())
.unwrap();
let fe = l.incoming()
.for_each(|(_sock, peer)| {
println!("Accepted from {}", peer);
Ok(())
})
.map_err(|e| println!("----- {:?}", e));
core.handle().spawn(fe);
}
// Listener1
{
let l = TcpListener::bind(&SocketAddr::from_str("127.0.0.1:55555").unwrap(),
&core.handle())
.unwrap();
let fe = l.incoming()
.for_each(|(_sock, peer)| {
println!("Accepted from {}", peer);
Ok(())
})
.map_err(|e| println!("----- {:?}", e));
core.handle().spawn(fe);
}
let work = rx.for_each(|v| {
if v {
// (3) I want to shut down listener-0 above the release the resources
Ok(())
} else {
Err(()) // <<<<<<<<<<<<<<< (2)
}
});
let _ = core.run(work);
println!("Exiting event loop thread");
});
let tx = get_rx.recv().unwrap();
thread::sleep(Duration::from_secs(2));
println!("Want to terminate listener-0"); // <<<<<< (3)
tx.send(true).unwrap();
thread::sleep(Duration::from_secs(2));
println!("Want to exit event loop");
tx.send(false).unwrap();
j.join().unwrap();
}
所以说在主线程睡眠后我想要事件循环线程的干净退出。目前我向事件循环发送一些东西以使其退出并释放线程。
但是,(1) 和 (2) 都感觉很老套——我是在强制一个错误作为退出条件。我的问题是:
1) 我做得对吗?如果不是,那么优雅退出事件循环线程的正确方法是什么。
2) 我不知道该怎么做(3) - 即在外部指示条件以关闭 listener-0 并释放它的所有资源。我如何做到这一点?
【问题讨论】:
标签: rust