1 个不稳定版本
0.1.0 | 2022年1月19日 |
---|
#7 in #ctrl-c
每月下载 32 次
在 splitar 中使用
13KB
234 行
interruptable
在 Rust 中为 Read
和 Write
提供可中断封装
用法
此包用于在信号处理库(如 ctrlc
)的配合下中断 IO。这些库可以处理接收到的信号并设置某些标志,但应用程序代码执行 IO 时,它无法在操作完成之前检查该标志。类 Unix 操作系统会在接收到信号时中断 IO 操作,返回 EINT
errno(即 ErrorKind::Interrupted
),但 std::io::
实用方法会静默地重新启动此类操作。
Interruptable
封装用于 std::io::Read
和 std::io::Write
会检查每个 read
或 write
操作的标志 (std::sync::atomic::AtomicBool
),当它看到标志被设置时,它会返回一个带有 std::io::Error
(IO 操作的标准错误)和一个嵌套的 ErrorKind::Other
和 ErrorKind::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?;
...
}