为在多线程环境中调用方法的结构添加生命周期
add lifetime for a struct that invoke method in multi-threading environment
这是我的程序:
use std::sync::{Arc, Mutex, MutexGuard};
use std::thread;
trait Animal: Send + Sync { fn get_id(&self) -> i32; }
struct Cat {}
impl Animal for Cat {
fn get_id(&self) -> i32 { return 0; }
}
struct Thread {
id: i32,
ptr: Arc<dyn Animal>,
}
impl Thread {
pub fn multi_threading(&self) {
let shared_array = Arc::new(Mutex::new([0; 5]));
let mut handles = vec![];
for _ in 0..5 {
let array_ptr = Arc::clone(&shared_array);
let handle = thread::spawn(move ||
self.assign(&mut array_ptr.lock().unwrap())
);
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
}
pub fn assign(&self, array: &mut MutexGuard<[i32; 5]>) {
array[self.id as usize] = self.id * self.id + self.ptr.get_id();
}
}
unsafe impl Send for Thread {}
fn main() {
let cat = Cat {};
let ptr_cat = Arc::new(cat);
let thread = Thread { id: 0, ptr: ptr_cat.clone() };
thread.multi_threading();
}
struct Thread
定义了一个指向 trait 对象的指针,它的成员方法 multi_threading
除了给一个可以被多个线程访问的数组赋值外什么都不做。
当我编译程序时,错误提示 &self
from pub fn multi_threading(&self)
has an anonymous lifetime '_
but it needs to satisfy a 'static
lifetime requirement
现在我应该在哪里添加这个 'static
生命周期来满足要求,让程序符合要求?
您可以将实例包装在 Arc
本身中。这样你就可以将它发送到你的线程:
impl Thread {
pub fn multi_threading(self: &Arc<Self>) {
let shared_array = Arc::new(Mutex::new([0; 5]));
let mut handles = vec![];
for _ in 0..5 {
let array_ptr = Arc::clone(&shared_array);
let s = self.clone();
let handle = thread::spawn(move ||
s.assign(&mut array_ptr.lock().unwrap())
);
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
}
pub fn assign(&self, array: &mut MutexGuard<[i32; 5]>) {
array[self.id as usize] = self.id * self.id + self.ptr.get_id();
}
}
...
fn main() {
let cat = Cat {};
let ptr_cat = Arc::new(cat);
let thread = Arc::new(Thread { id: 0, ptr: ptr_cat.clone() });
thread.multi_threading();
}
请注意,您不需要 unsafe impl Send for Thread {}
,因为 Arc
可以安全地共享它。
这是我的程序:
use std::sync::{Arc, Mutex, MutexGuard};
use std::thread;
trait Animal: Send + Sync { fn get_id(&self) -> i32; }
struct Cat {}
impl Animal for Cat {
fn get_id(&self) -> i32 { return 0; }
}
struct Thread {
id: i32,
ptr: Arc<dyn Animal>,
}
impl Thread {
pub fn multi_threading(&self) {
let shared_array = Arc::new(Mutex::new([0; 5]));
let mut handles = vec![];
for _ in 0..5 {
let array_ptr = Arc::clone(&shared_array);
let handle = thread::spawn(move ||
self.assign(&mut array_ptr.lock().unwrap())
);
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
}
pub fn assign(&self, array: &mut MutexGuard<[i32; 5]>) {
array[self.id as usize] = self.id * self.id + self.ptr.get_id();
}
}
unsafe impl Send for Thread {}
fn main() {
let cat = Cat {};
let ptr_cat = Arc::new(cat);
let thread = Thread { id: 0, ptr: ptr_cat.clone() };
thread.multi_threading();
}
struct Thread
定义了一个指向 trait 对象的指针,它的成员方法 multi_threading
除了给一个可以被多个线程访问的数组赋值外什么都不做。
当我编译程序时,错误提示 &self
from pub fn multi_threading(&self)
has an anonymous lifetime
'_
but it needs to satisfy a'static
lifetime requirement
现在我应该在哪里添加这个 'static
生命周期来满足要求,让程序符合要求?
您可以将实例包装在 Arc
本身中。这样你就可以将它发送到你的线程:
impl Thread {
pub fn multi_threading(self: &Arc<Self>) {
let shared_array = Arc::new(Mutex::new([0; 5]));
let mut handles = vec![];
for _ in 0..5 {
let array_ptr = Arc::clone(&shared_array);
let s = self.clone();
let handle = thread::spawn(move ||
s.assign(&mut array_ptr.lock().unwrap())
);
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
}
pub fn assign(&self, array: &mut MutexGuard<[i32; 5]>) {
array[self.id as usize] = self.id * self.id + self.ptr.get_id();
}
}
...
fn main() {
let cat = Cat {};
let ptr_cat = Arc::new(cat);
let thread = Arc::new(Thread { id: 0, ptr: ptr_cat.clone() });
thread.multi_threading();
}
请注意,您不需要 unsafe impl Send for Thread {}
,因为 Arc
可以安全地共享它。