У меня есть поток, который периодически вызывает функцию обратного вызова. В зависимости от состояния функция обратного вызова должна получить RwLock
ресурса, совместно используемого другими потоками, и заблокировать доступ к ресурсу даже за пределами функции обратного вызова. Затем он снова в зависимости от состояния освобождает ресурс снова в более позднем цикле обратного вызова.Приобретение RwLock для чтения и сохранения его за пределами области
Моей идеей было положить в структуру, которая была бы None
, когда ресурс не заблокирован и Some(RwLockReadGuard<T>)
, когда ресурс заблокирован.
К сожалению, я не могу выполнить эту работу. Я должен создать структуру, которая содержит вне потока функции обратного вызова. Несмотря на то, что в то время, когда структура перемещается в поток, Option
является None
, компилятор не позволит мне передать этот параметр, потому что the trait bound ``std::sync::RwLockReadGuard<'_, T>: std::marker::Send`` is not satisfied
.
Возможно, какой-то код. Надеюсь, это достаточно объяснительно.
use std::thread;
use std::sync::{Arc, RwLock, RwLockReadGuard};
struct Handler<'a> {
resource: Arc<RwLock<String>>,
locked_resource: Option<RwLockReadGuard<'a, String>>,
counter: usize,
}
impl<'a> Handler<'a> {
fn callback(&'a mut self) {
println!("Callback {}", self.counter);
if self.counter == 0 {
println!("Locking resource");
let res = self.resource.read().unwrap();
self.locked_resource = Some(res);
}
self.counter += 1;
if self.counter == 100 {
println!("Releasing resource");
self.locked_resource = None;
}
if self.counter == 200 {
self.counter = 0;
}
}
}
fn main() {
let resource = Arc::new(RwLock::new("foo".to_string()));
let handler = Handler {
resource: resource.clone(),
locked_resource: None,
counter: 0
};
// This gives E0277
let thread = thread::spawn(move || {
loop {
handler.callback();
}
});
}
Я подумал об этом и попробовал ваше решение. Но тогда он говорит, что «обработчик может не прожить достаточно долго». Но это не вариант, так как в моем реальном проекте я сам не настраиваю нить. Я просто передаю объект-признак с функцией обратного вызова, и библиотека запускает поток. –
Интересная ошибка, которая не имеет ничего общего с вопросом 'Mutex': вы не можете [брать у брата] (http://stackoverflow.com/questions/32300132/why-cant-i-store-a-value-and -a ссылка к этой стоимости-в-же-структуры). Что касается вашей проблемы, извините, но это правила. Вы не можете блокировать нить, разблокировать из другого потока и ожидать, что все будет работать: вы * имеете *, чтобы проектировать свою программу по-другому. –
Но это тот же поток, не так ли? Это один поток, который снова и снова вызывает callback(). Я хочу, чтобы он удерживал замок на нескольких из этих циклов. –