concurrency - 动态调度和线程

标签 concurrency rust

我目前正在研究 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 不携带该信息。您必须确保 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 );
}

关于concurrency - 动态调度和线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28848814/

相关文章:

mysql - 使用可重复读取隔离时 SELECT .. FOR UPDATE 有什么用?

concurrency - Erlang中的并发及其适当的工作流程

java - Java 会自动异步调用这些方法吗?

rust - 为什么在函数返回时从 `HashMap::get`借用还没有结束?

c - 如何在 C 中动态加载 Rust 库?

rust - 在谓词失败后在迭代器中获取一个额外元素的规范方法是什么?

rust - 如何在 Rust 中正确实现 Error::cause?

rust - 在另一个线程中从 `panic!` 恢复

c# - 并发读写 NamePipeClientStream

java - 什么时候适合多线程?