Rust `RefCell<;std::string::string>;`无法在线程之间安全地共享?
这是新Q的延续,为了更好地展示Rust `RefCell<;std::string::string>;`无法在线程之间安全地共享?,rust,hyper,Rust,Hyper,这是新Q的延续,为了更好地展示 //main.rs //该值最终将在“main”中修改 //http请求应该以其持有的任何“当前”值进行响应。 让mut测试_的闭包:Arc=Arc::new(RefCell::from(“Foo.”to_string()); // ... //HTTP请求的处理程序 //从https://docs.rs/hyper/0.14.8/hyper/service/fn.service_fn.html 设make_svc=make_service_fn(| | u co
//main.rs
//该值最终将在“main”中修改
//http请求应该以其持有的任何“当前”值进行响应。
让mut测试_的闭包:Arc=Arc::new(RefCell::from(“Foo.”to_string());
// ...
//HTTP请求的处理程序
//从https://docs.rs/hyper/0.14.8/hyper/service/fn.service_fn.html
设make_svc=make_service_fn(| | u conn | async{
Ok::(服务|请求|异步移动{
if req.version()==version::HTTP_11{
让foo:String=*为_闭包测试_。借用();
确定(响应::新建(主体::from(foo.as_str()))
}否则{
错误(“非HTTP/1.1,中止连接”)
}
}))
});
不幸的是,我得到的RefCell无法在线程之间安全地共享:
错误消息中的第一个错误是,RefCell
未实现Sync
。这是设计的,如Sync
所述:
不同步的类型是那些在一个系统中具有“内部可变性”的类型
非线程安全形式,如单元格和RefCell。这些类型允许
即使通过一个不变的、共享的
参考资料。例如,单元格上的set方法采用&self,因此
只需要共享引用和单元格。该方法不执行任何操作
同步,因此单元格不能同步
因此,在线程之间共享refcell是不安全的,因为您可以通过常规的共享引用引起数据竞争
但是如果你把它包装成弧
?嗯,问题又很清楚了:
只要T实现发送,Arc就会实现发送和同步
和同步。为什么你不能把一个非线程安全的t型放在一个弧中
确保线程安全?起初,这可能有点违反直觉:
毕竟,圆弧螺纹的安全性不是很重要吗?关键是:
Arc使拥有同一个文件的多个所有权成为线程安全的
数据,但它不会为其数据添加线程安全性。考虑
弧。RefCell不同步,如果Arc始终处于发送状态,
Arc也可以。但是我们会遇到一个问题:
RefCell不是线程安全的;它跟踪借款数量
使用非原子操作
最后,这意味着您可能需要将圆弧与某种类型的圆弧配对
属于std::sync类型,通常为互斥
Arc
将不会Sync
除非T
由于同样的原因是Sync
。鉴于此,您可能应该使用std/tokioMutex
,而不是RefCell
RefCell只能在单线程上工作。您将需要使用类似的互斥锁,但它可以在多个线程上工作。您可以在此处阅读有关互斥的更多信息:
以下是将圆弧移动到闭合中的示例:
use std::sync::{Arc, Mutex};
fn main() {
let mut test: Arc<Mutex<String>> = Arc::new(Mutex::from("Foo".to_string()));
let mut test_for_closure = Arc::clone(&test);
let closure = || async move {
// lock it so it cant be used in other threads
let foo = test_for_closure.lock().unwrap();
println!("{}", foo);
};
}
使用std::sync::{Arc,Mutex};
fn main(){
让mut测试:Arc=Arc::new(Mutex::from(“Foo.”to_string());
让mut测试_,以确定_closure=Arc::clone(&test);
让闭包=| |异步移动{
//锁定它,使其不能在其他线程中使用
设foo=test_for_closure.lock().unwrap();
println!(“{}”,foo);
};
}
是否克隆Arc?此部分在代码中不可见。请参阅。请将错误复制为问题中的文本。不要将其作为截图:根据观众的屏幕分辨率,图像可能很难阅读,其他有类似问题的人无法搜索。再次非常感谢!还有一些黑魔法,因为现在借来的价值活得不够长。我做了一个跟进Q,如果你想看一看:非常感谢你的详细解释!现在这对我来说更有意义了。我尝试了一个互斥,它更进一步,但有一个不同的错误。如果你想看一看,我在这里做了一个跟进问题: