我目前正在研究 Rust 中的并发性,遇到了以下问题。给定一个没有具体类型但使用动态分派(dispatch)的引用,似乎不可能在不同的线程中调用它的任何函数。这是一个最小的例子:
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
甚至没有任何可以阻止它被共享的数据。所以我假设我只是设置错误。我在这里的想法是否正确?如果正确,我该如何编译它?
最佳答案
原因是任何 S1 都是 Sync
,但 T 不携带该信息。您必须确保 pointer
是 Sync
,即使没有信息表明它是 S1。有多种方法可以做到这一点:
使特征始终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 );
}
关于concurrency - 动态调度和线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28848814/