【发布时间】:2020-06-13 18:28:48
【问题描述】:
我有一个 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 外部执行时的行为是相同的。
【问题讨论】:
-
用 Rust 等编译语言中止线程不是安全操作:它会使进程处于未确定状态。
-
我的 rust 线程是只读的。有没有办法绕过这个限制?
-
“只读线程”是什么意思?线程不能安全地取消,期间。现在,
async期货被设计为可以在特定点取消(即await),但我不知道 PyO3 是否支持它们。
标签: python rust keyboardinterrupt pyo3