我目前正在使用Rust中的并发性,而且我遇到了以下问题。给定一个没有具体类型的引用,但是使用动态分派的引用似乎不可能在不同的线程中调用它上面的任何函数。这是一个最小的例子:
use std::thread;
trait T {
fn func(&self);
}
struct S1;
impl S1 {
pub fn new() -> S1 {
S1
}
}
impl T for S1 {
fn func(&self) {}
}
fn main() {
let reference: &T = &S1::new();
thread::scoped(|| reference );
}
尝试编译这会导致以下错误:
uh@macaron:~$ rustc test.rs
test.rs:21:5: 21:19 error: the trait `core::marker::Sync` is not implemented for the type `T` [E0277]
test.rs:21 thread::scoped(|| reference );
^~~~~~~~~~~~~~
test.rs:21:5: 21:19 note: `T` cannot be shared between threads safely
test.rs:21 thread::scoped(|| reference );
^~~~~~~~~~~~~~
test.rs:21:5: 21:19 error: the trait `core::marker::Sync` is not implemented for the type `T` [E0277]
test.rs:21 thread::scoped(|| reference );
^~~~~~~~~~~~~~
test.rs:21:5: 21:19 note: `T` cannot be shared between threads safely
test.rs:21 thread::scoped(|| reference );
^~~~~~~~~~~~~~
error: aborting due to 2 previous errors
我会天真地认为这可行,因为S1
甚至没有任何数据可以阻止它被共享。所以我认为我只是把它设置错了。我在这里是否正确思考,如果是这样,我该如何编译?
答案 0 :(得分:3)
原因是任何S1都是Sync
,但T不会携带该信息。即使没有S1的信息,您也必须确保pointer
为Sync
。有多种方法可以做到这一点:
使特征始终为Sync
:
trait T : Sync {
fn func(&self);
}
制作指针T+Sync
:
fn main() {
let pointer: &(T + Sync) = &S1::new();
thread::scoped(|| pointer );
}
使用实际类型作为指针的类型,通过陈述或推断(这不适合问题,但我想记录清楚):
fn main() {
let pointer: &S1 = &S1::new();
thread::scoped(|| pointer );
}
fn main() {
let pointer = &S1::new();
thread::scoped(|| pointer );
}