gpt4 book ai didi

multithreading - 获取一个 RwLock 用于读取并使其超出范围

转载 作者:行者123 更新时间:2023-11-29 08:06:21 25 4
gpt4 key购买 nike

我有一个定期调用回调函数的线程。根据状态,回调函数应获取 RwLock。与其他线程共享的资源,并保持资源锁定,甚至超出回调函数的范围。然后它将根据状态在稍后的回调周期中再次释放资源。

我的想法是放一个 Option<RwLockReadGuard<T>>进入结构 None当资源未锁定且 Some(RwLockReadGuard<T>)当资源被锁定时。

不幸的是,我无法完成这项工作。我必须设置包含 Option<RwLockReadGuard<T>> 的结构在回调函数的线程之外。即使当时结构被移入线程中,OptionNone ,编译器不会让我传递选项,因为 the trait bound ``std::sync::RwLockReadGuard<'_, T>: std::marker::Send`` is not satisfied .

也许是一些代码。我希望这足以 self 解释。

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();
}
});
}

最佳答案

问题是:锁定和解锁需要发生在同一个线程上。例如,这是 pthread 的限制。 .

幸运的是,Rust 类型系统的表现力足以对此进行建模:通过使 RwLockReadGuard 成为 !Send,它可以防止锁被意外共享!向 Rust 致敬!

因此您可以在不同的回调函数中锁定和解锁...但在同一个线程上。

在您的示例中,这就像在线程内移动 handler 的创建一样简单。在您的实际应用程序中,它可能会稍微复杂一些,但请放心:编译器会一路牵着您的手 ;)

fn main() {
let resource = Arc::new(RwLock::new("foo".to_string()));

let thread = thread::spawn( move || {
let handler = Handler {
resource: resource,
locked_resource: None,
counter: 0
};

loop {
handler.callback();
}
});
}

关于multithreading - 获取一个 RwLock 用于读取并使其超出范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41641721/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com