multithreading - 让 Rust 线​​程摆脱阻塞操作的标准方法是什么?

标签 multithreading rust terminate

来自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 中的实现方式,我发现提到了许多看似特殊的解决方案,例如 miotokio。我还找到了 ErrorKind::Interrupted 并尝试通过向线程发送 SIGINT 来获取此 ErrorKind ,但线程似乎立即死亡而没有离开任何(回)迹。

这是我使用的代码(注意:还不是很精通 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();
}

我所说的“阻塞操作”是指:

  • sleep
  • 套接字输入输出
  • 文件输入输出
  • 队列 IO(还不确定队列在 Rust 中的位置)

向线程发出信号的相应方法是什么,例如 Java 中的 Thread.interrupt(),该收拾行李回家了?

最佳答案

没有这样的东西。堵就是堵。

相反,您故意使用非阻塞 的工具。这就是 mio、Tokio 或 futures 等库的用武之地——它们处理将所有这些非阻塞、异步部分粘在一起的架构。

catch (InterruptedException e)

Rust 没有异常(exception)。如果您希望处理失败情况,最好用 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();
}

sleep

据我所知,没有办法打断。文档甚至说:

On Unix platforms this function will not return early due to a signal

套接字输入输出

你使用类似于set_nonblocking 的方法将套接字置于非阻塞模式然后处理 ErrorKind::WouldBlock .

另见:

文件输入输出

执行异步文件 IO 的真正跨平台方式并不好。大多数实现会启动一个线程池并在那里执行阻塞操作,通过非阻塞的方式发送数据。

另见:

队列IO

也许你的意思是像 MPSC channel 这样的东西,在这种情况下,您将使用 try_recv 等工具.

另见:

关于multithreading - 让 Rust 线​​程摆脱阻塞操作的标准方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52465480/

相关文章:

c - 非嵌入式系统的 RTOS 邮箱示例

Java CompletableFuture.runAsync 递归...有潜在风险吗?

rust - 通过 rust 进行 LLVM 调试输出

rust - Vec和HashMap之间的特征对象差异

node.js - Node 杀死线程但不杀死进程

c# - 线程同步c#

java - 具有offer和flush的非阻塞并发队列

rust - 使用函数指针时为 "Expected fn item, found a different fn item"

ios - 应用程序终止时停止位置更新

c++ - 停止执行而不跳过析构函数