来自Java,我习惯于成语
while (true) {
try {
someBlockingOperation();
} catch (InterruptedException e) {
Thread.currentThread.interrupt(); // re-set the interrupted flag
cleanup(); // whatever is necessary
break;
}
}
据我所知,这在整个JDK上都适用于可能阻塞的所有内容,例如从文件,套接字,队列甚至Thread.sleep()
读取。
通过阅读Rust中的完成方式,我发现了许多看似特殊的解决方案,例如mio
,tokio
。我还找到了ErrorKind::Interrupted
,并尝试通过向线程发送ErrorKind
来获取此SIGINT
,但是该线程似乎立即死亡而没有留下任何(返回)跟踪。
这是我使用的代码(注意:Rust还不很精通,因此看起来可能有些奇怪,但是可以运行):
use std::io;
use std::io::Read;
use std::thread;
pub fn main() {
let sub_thread = thread::spawn(|| {
let mut buffer = [0; 10];
loop {
let d = io::stdin().read(&mut buffer);
println!("{:?}", d);
let n = d.unwrap();
if n == 0 {
break;
}
println!("-> {:?}", &buffer[0..n]);
}
});
sub_thread.join().unwrap();
}
通过“阻止操作”,我的意思是:
向线程(例如Java中的Thread.interrupt()
)发出信号通知其打包时间回家的分别意味着什么?
答案 0 :(得分:4)
没有这样的事情。阻止意味着阻止。
相反,您故意使用了非阻塞的工具。那就是像mio或futures之类的库进入的地方-它们处理将所有这些非阻塞的异步块粘贴在一起的体系结构。
catch (InterruptedException e)
Rust没有例外。如果您希望处理失败的情况,最好用Result
来表示。
Thread.interrupt()
除了在线程中设置一些代码可能会检查然后引发异常的标志之外,这实际上没有做任何事情。您可以自己构建相同的结构。一个简单的实现:
use std::{
sync::{
atomic::{AtomicBool, Ordering},
Arc,
},
thread,
time::Duration,
};
fn main() {
let please_stop = Arc::new(AtomicBool::new(false));
let t = thread::spawn({
let should_i_stop = please_stop.clone();
move || {
while !should_i_stop.load(Ordering::SeqCst) {
thread::sleep(Duration::from_millis(100));
println!("Sleeping");
}
}
});
thread::sleep(Duration::from_secs(1));
please_stop.store(true, Ordering::SeqCst);
t.join().unwrap();
}
据我所知,没有中断的方法。该文档甚至说:
在Unix平台上,此功能将由于信号而不会提早返回
您可以使用set_nonblocking
之类的方法将套接字置于非阻塞模式,然后处理ErrorKind::WouldBlock
。
执行异步文件IO确实没有很好的跨平台方法。大多数实现会启动线程池并在那里执行阻塞操作,通过不阻塞的东西发送数据。
也许您的意思是类似MPSC channel的东西,在这种情况下,您将使用try_recv
之类的工具。
另请参阅: