[英]What is the standard way to get a Rust thread out of blocking operations?
Coming from Java, I am used to idioms along the lines of来自Java,我习惯了类似的成语
while (true) {
try {
someBlockingOperation();
} catch (InterruptedException e) {
Thread.currentThread.interrupt(); // re-set the interrupted flag
cleanup(); // whatever is necessary
break;
}
}
This works, as far as I know, across the whole JDK for anything that might block, like reading from files, from sockets, from a queue and even for Thread.sleep()
.据我所知,这适用于整个 JDK 中任何可能阻塞的内容,例如从文件、套接字、队列甚至
Thread.sleep()
读取。
Reading on how this is done in Rust, I find lots of seemingly special solutions mentioned like mio
, tokio
.阅读如何在 Rust 中完成此操作,我发现提到了许多看似特殊的解决方案,例如
mio
、 tokio
。 I also find ErrorKind::Interrupted
and tried to get this ErrorKind
with sending SIGINT
to the thread, but the thread seems to die immediately without leaving any (back)trace.我还发现
ErrorKind::Interrupted
并尝试通过向线程发送SIGINT
来获取此ErrorKind
,但线程似乎立即死亡而没有留下任何(回溯)跟踪。
Here is the code I used (note: not very well versed in Rust yet, so it might look a bit strange, but it runs):这是我使用的代码(注意:还不是很精通 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();
}
By "blocking operations", I mean:通过“阻止操作”,我的意思是:
What would be the respective means to signal to a thread, like Thread.interrupt()
in Java, that its time to pack up and go home?分别向线程发出信号的方法是什么,比如 Java 中的
Thread.interrupt()
,是时候打包回家了?
There is no such thing.哪有这回事。 Blocking means blocking.
阻塞意味着阻塞。
Instead, you deliberately use tools that are non-blocking .相反,您故意使用非阻塞的工具。 That's where libraries like mio, Tokio, or futures come in — they handle the architecture of sticking all of these non-blocking, asynchronous pieces together.
这就是像 mio、Tokio 或 futures 这样的库的用武之地——它们处理将所有这些非阻塞、异步部分粘在一起的架构。
catch (InterruptedException e)
Rust doesn't have exceptions. Rust 没有例外。 If you expect to handle a failure case, that's better represented with a
Result
.如果您希望处理失败案例,最好用
Result
来表示。
Thread.interrupt()
This doesn't actually do anything beyond setting a flag in the thread that some code may check and then throw an exception for.除了在线程中设置一些代码可能检查然后抛出异常的标志之外,这实际上并没有做任何事情。 You could build the same structure yourself.
您可以自己构建相同的结构。 One simple implementation:
一个简单的实现:
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();
}
No way of interrupting, as far as I know.据我所知,没有办法打断。 The documentation even says:
文档甚至说:
On Unix platforms this function will not return early due to a signal
在 Unix 平台上,此函数不会因为信号而提前返回
You put the socket into nonblocking mode using methods like set_nonblocking
and then handle ErrorKind::WouldBlock
.您使用
set_nonblocking
等方法将套接字置于非阻塞模式,然后处理ErrorKind::WouldBlock
。
See also:也可以看看:
There isn't really a good cross-platform way of performing asynchronous file IO.执行异步文件 IO 并没有真正好的跨平台方式。 Most implementations spin up a thread pool and perform blocking operations there, sending the data over something that does non-blocking.
大多数实现都会启动一个线程池并在那里执行阻塞操作,通过非阻塞的方式发送数据。
See also:也可以看看:
Perhaps you mean something like a MPSC channel , in which case you'd use tools like try_recv
.也许您的意思是MPSC 频道之类的东西,在这种情况下,您会使用诸如
try_recv
类的工具。
See also:也可以看看:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.