动态调度和线程

Dynamic dispatch and threads

我目前正在研究 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 甚至没有任何数据可以阻止它被共享。所以我假设我只是设置错误。我在这里的想法是否正确?如果正确,我该如何编译它?

原因是任何 S1 都是 Sync,但 T 不携带该信息。你必须确保 pointerSync 即使没有信息表明它是 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 );
}