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,并尝试通过向该线程发送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();
}

我所说的“阻止操作”是指:
  • sleep
  • 套接字IO
  • 文件IO
  • 队列IO(尚不确定队列在Rust中的位置)

  • 向线程发出信号(例如Java中的Thread.interrupt())的信号分别是什么?

    最佳答案

    哪有这回事。阻塞意味着阻塞。

    相反,您有意使用非阻塞工具。那就是mio,Tokio或Future之类的库进入的地方-它们处理将所有这些非阻塞,异步块粘贴在一起的体系结构。

    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



    插槽IO

    您可以使用 set_nonblocking 之类的方法将套接字置于非阻塞模式,然后处理 ErrorKind::WouldBlock

    也可以看看:
  • Tokio
  • async-std

  • 文件IO

    实际上,没有很好的跨平台方法来执行异步文件IO。大多数实现会启动线程池并在那里执行阻塞操作,通过非阻塞的方式发送数据。

    也可以看看:
  • Tokio
  • async-std

  • 队列IO

    也许您的意思是像MPSC channel之类的东西,在这种情况下,您将使用 try_recv 之类的工具。

    也可以看看:
  • How to terminate or suspend a Rust thread from another thread?
  • What is the best approach to encapsulate blocking I/O in future-rs?
  • What does java.lang.Thread.interrupt() do?
  • 关于multithreading - 使Rust线程退出阻塞操作的标准方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66213351/

    相关文章:

    kubernetes - 如何在Kubernetes中完成等待荚终止直到当前进程完成?

    c++ - 直观的线程安全

    python - 创建一个类似 eclipse 的终止按钮

    java - 如何在Red5中创建线程?

    rust - 使用特征作为数据库实体的接口(interface)

    generics - 泛型结构的构造函数中出现 "Expected type parameter"错误

    performance - Rust - 为什么我的程序执行速度非常慢 - 比使用 Node 用 Ja​​vaScript 编写的相同程序慢 5 倍以上

    python - 如何在终止 Python 脚本时运行清理

    c# - 优雅地关闭多线程应用程序?

    c++ - C++ 静态成员变量初始化线程安全吗?