拉斯特一个非常普遍的模式是Arc<Mutex<T>>,这里Arc提供了内存管理,并Mutex提供安全的多线程访问资源.还有什么可以代替Arc,在什么情况下使用?
我正在编写一个WebSocket服务器,其中一个Web客户端连接到多线程计算机AI上下棋.WebSocket服务器想要将Logger对象传递给AI代码.该Logger对象将管理从AI到Web客户端的日志行.在Logger必须包含对客户端连接的参考.
我对生命周期如何与线程交互感到困惑.我用Wrapper类型参数化的结构重现了这个问题.该run_thread函数尝试解包该值并记录它.
use std::fmt::Debug;
use std::thread;
struct Wrapper<T: Debug> {
val: T,
}
fn run_thread<T: Debug>(wrapper: Wrapper<T>) {
let thr = thread::spawn(move || {
println!("{:?}", wrapper.val);
});
thr.join();
}
fn main() {
run_thread(Wrapper::<i32> { val: -1 });
}
Run Code Online (Sandbox Code Playgroud)
该wrapper参数存在于堆栈中,并且它的生命周期不会延伸超过run_thread堆栈帧,即使该线程将在堆栈帧结束之前连接.我可以从堆栈中复制值:
use std::fmt::Debug;
use std::thread;
struct Wrapper<T: Debug + Send> {
val: T,
}
fn run_thread<T: Debug + Send + 'static>(wrapper: Wrapper<T>) {
let thr = thread::spawn(move || …Run Code Online (Sandbox Code Playgroud) 我正在学习并发性,并希望澄清我对Rust书中以下代码示例的理解.如果我错了,请纠正我.
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
fn main() {
let data = Arc::new(Mutex::new(vec![1, 2, 3]));
for i in 0..3 {
let data = data.clone();
thread::spawn(move || {
let mut data = data.lock().unwrap();
data[0] += i;
});
}
thread::sleep(Duration::from_millis(50));
}
Run Code Online (Sandbox Code Playgroud)
线路上发生了let data = data.clone()什么?
Rust书说
我们
clone()用来创建一个新拥有的句柄.然后将此句柄移动到新线程中.
什么是新的"拥有的手柄"?这听起来像是对数据的引用?
由于clonea &self和a 返回一个Self,是每个线程修改原始数据而不是副本?我猜这就是为什么代码没有使用data.copy()但data.clone()在这里.
在data右侧是一个参考,而data左边是一个拥有价值.这里有一个变量阴影.
我正在尝试在Rust中使用线程之间共享一个可变对象Arc,但是我收到了这个错误:
error[E0596]: cannot borrow data in a `&` reference as mutable
--> src/main.rs:11:13
|
11 | shared_stats_clone.add_stats();
| ^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
Run Code Online (Sandbox Code Playgroud)
这是示例代码:
use std::{sync::Arc, thread};
fn main() {
let total_stats = Stats::new();
let shared_stats = Arc::new(total_stats);
let threads = 5;
for _ in 0..threads {
let mut shared_stats_clone = shared_stats.clone();
thread::spawn(move || {
shared_stats_clone.add_stats();
});
}
}
struct Stats {
hello: u32,
}
impl Stats {
pub fn new() -> Stats {
Stats { hello: 0 …Run Code Online (Sandbox Code Playgroud) 我有一个在main(第 9 行)中初始化的变量,我想在我的一个路由处理程序中访问对这个变量的引用。
#[get("/")]
fn index() -> String {
return fetch_data::fetch(format!("posts"), &redis_conn).unwrap(); // How can I get redis_conn?
}
fn main() {
let redis_conn = fetch_data::get_redis_connection(); // initialized here
rocket::ignite().mount("/", routes![index]).launch();
}
Run Code Online (Sandbox Code Playgroud)
在其他语言中,这个问题可以通过使用全局变量来解决。
我的理解是,在Rust中的任务之间共享可变状态是不可能的,那么为什么Rust 在语言中有像互斥体这样的东西呢?他们的目的是什么?