我正在使用pyo3制作一个Python模块,用Rust编写,它将:
到目前为止,我的代码如下所示:
use std::thread;
use pyo3::prelude::*;
#[pyclass]
struct CountWatcher {
// The number of the GPIO pin we'll be watching
// Can't be read from Python
pin: u8,
// How many times the pin changed state
// Can be read from Python
#[pyo3(get)]
count: u128,
// Thread handle
t: thread::JoinHandle<()>,
}
#[pymethods]
impl CountWatcher {
#[new]
fn new(pin: u8) -> Self {
let t = thread::spawn(|| {
loop {
// This is where the code that reads the GPIO pin, and increments count will eventually go
println!("Test");
std::thread::sleep(std::time::Duration::from_secs(1));
}
});
Self {
pin,
count: 0,
t: t,
}
}
}
#[pymodule]
fn countwatcher(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_class::<CountWatcher>()?;
Ok(())
}
这段代码可以工作,但我遇到的问题是如何在线程中获取对实例的引用,以便我可以更新count
,同时仍然允许Python随时检查count
我原以为这样做行得通,但事实并非如此:
fn new(pin: u8) -> Arc<Self> {
let mut inst = Self {
pin,
count: 0,
t: None,
};
let mut inst_1 = Arc::new(inst);
let mut inst_2 = inst_1.clone();
let t = thread::spawn(move || {
loop {
inst_1.count += 1;
std::thread::sleep(std::time::Duration::from_secs(1));
}
});
inst_2.t = Some(t);
inst_2
}
注意,我必须将结构的t
类型转换为Option<thread::JoinHandle()>>
,因为在这里,我需要在创建线程之前创建实例。另外,我的new
方法现在返回的是一个Arc<Self>
,而不仅仅是Self
,我不完全确定是否允许这样做
我也尝试过使用Arc<Mutex<CountWatcher>>
,但是我需要从new返回一个Arc<Mutex<CountWatcher>>
,或者返回inst_2.lock()
,这将永久锁定它
目前没有回答
相关问题 更多 >
编程相关推荐