У меня есть библиотека Python, написанная на Rust с PyO3, и она требует некоторых дорогостоящих вычислений (до 10 минут на один вызов функции). Как я могу прервать выполнение при вызове из Python?
Ctrl+C, по-видимому, обрабатывается только после окончания выполнения, поэтому по сути бесполезен.
Минимальный воспроизводимый пример:
# Cargo.toml
[package]
name = "wait"
version = "0.0.0"
authors = []
edition = "2018"
[lib]
name = "wait"
crate-type = ["cdylib"]
[dependencies.pyo3]
version = "0.10.1"
features = ["extension-module"]
// src/lib.rs
use pyo3::wrap_pyfunction;
#[pyfunction]
pub fn sleep() {
std::thread::sleep(std::time::Duration::from_millis(10000));
}
#[pymodule]
fn wait(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(sleep))
}
$ rustup override set nightly
$ cargo build --release
$ cp target/release/libwait.so wait.so
$ python3
>>> import wait
>>> wait.sleep()
Сразу после ввода wait.sleep()
я набираю Ctrl + C
, и символы ^C
печатаются на экране, но только через 10 секунд я наконец получаю
>>> wait.sleep()
^CTraceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyboardInterrupt
>>>
KeyboardInterrupt
был обнаружен, но остался необработанным до конца вызова функции Rust. Есть ли способ обойти это?
Поведение такое же, когда код Python помещается в файл и выполняется вне REPL.
async
предназначены для отмены в определенных точках (например,await
), но я не знаю, поддерживает ли их PyO3. - person mcarton   schedule 13.06.2020