#read-write #ctrl-c #signal #io-write

interruptable

可中断读写封装

1 个不稳定版本

0.1.0 2022年1月19日

#7 in #ctrl-c

每月下载 32
splitar 中使用

MIT 许可证

13KB
234

interruptable

在 Rust 中为 ReadWrite 提供可中断封装

用法

此包用于在信号处理库(如 ctrlc)的配合下中断 IO。这些库可以处理接收到的信号并设置某些标志,但应用程序代码执行 IO 时,它无法在操作完成之前检查该标志。类 Unix 操作系统会在接收到信号时中断 IO 操作,返回 EINT errno(即 ErrorKind::Interrupted),但 std::io:: 实用方法会静默地重新启动此类操作。

Interruptable 封装用于 std::io::Readstd::io::Write 会检查每个 readwrite 操作的标志 (std::sync::atomic::AtomicBool),当它看到标志被设置时,它会返回一个带有 std::io::Error(IO 操作的标准错误)和一个嵌套的 ErrorKind::OtherErrorKind::Interrupted 错误的 std::io::Error,从而将其隐藏在重试逻辑中。

没有 interruptabe 的生活

use std::io;
use std::sync::atomic;
use ctrlc;

let interrupt_flag = atomic::Arc::new(atomic::AtomicBool::new(false));
let interrput_flag2 = interrupt_flag.clone();

ctrlc::set_handler(move || {
    interrput_flag2.store(true, std::sync::atomic::Ordering::SeqCst);
}).unwrap();

let file = io::BufReader::new(
   std::fs::File::open("/path/to/slow/media/data.data")?
);

let my_precious_resource = MyResource::new();

for line in file.lines() {
    // It will be checked only after whole line is read, that may
    // take arbitrary long time.
    if interrput_flag2.load(std::sync::atomic::Ordering::SeqCst) {
        std::mem::drop(my_precious_resource);
        std::process::exit(42);
    }
    let line = line?;
    ...
}

有了 interruptabe 的生活

use std::io;
use std::sync::atomic;
use ctrlc;

let interrupt_flag = atomic::Arc::new(atomic::AtomicBool::new(false));
let interrput_flag2 = interrupt_flag.clone();

ctrlc::set_handler(move || {
    interrput_flag2.store(true, std::sync::atomic::Ordering::SeqCst);
}).unwrap();

let file = io::BufReader::new(
    // Work both for Read and Write.
    interruptable::Interruptable::new(
        std::fs::File::open("/path/to/slow/media/data.data")?,
        interrupt_flag,
    )
);

let my_precious_resource = MyResource::new();

for line in file.lines() {
    // When the signal will arrive and flag is set, line will be Err(...)
    // immediately, thus you will be able to handle it and gracefully
    // shutdown your application: my_precious_resource is destroyed
    // in the standard way, by Drop::drop.
    let line = line?;
    ...
}

无运行时依赖