相关疑难解决方法(0)

如何将对堆栈变量的引用传递给线程?

我正在编写一个WebSocket服务器,其中一个Web客户端连接到多线程计算机AI上下棋.WebSocket服务器想要将Logger对象传递给AI代码.该Logger对象将管理从AI到Web客户端的日志行.在Logger必须包含对客户端连接的参考.

我对生命周期如何与线程交互感到困惑.我用Wrapper类型参数化的结构重现了这个问题.该run_thread函数尝试解包该值并记录它.

use std::fmt::Debug;
use std::thread;

struct Wrapper<T: Debug> {
    val: T,
}

fn run_thread<T: Debug>(wrapper: Wrapper<T>) {
    let thr = thread::spawn(move || {
        println!("{:?}", wrapper.val);
    });

    thr.join();
}

fn main() {
    run_thread(Wrapper::<i32> { val: -1 });
}
Run Code Online (Sandbox Code Playgroud)

wrapper参数存在于堆栈中,并且它的生命周期不会延伸超过run_thread堆栈帧,即使该线程将在堆栈帧结束之前连接.我可以从堆栈中复制值:

use std::fmt::Debug;
use std::thread;

struct Wrapper<T: Debug + Send> {
    val: T,
}

fn run_thread<T: Debug + Send + 'static>(wrapper: Wrapper<T>) {
    let thr = thread::spawn(move || …
Run Code Online (Sandbox Code Playgroud)

rust

22
推荐指数
1
解决办法
3771
查看次数

如何保证在线程之间实际可以安全地共享未实现Sync的类型?

我有代码创建一个RefCell然后想要将它的引用传递RefCell单个线程:

extern crate crossbeam;

use std::cell::RefCell;

fn main() {
    let val = RefCell::new(1);

    crossbeam::scope(|scope| {
        scope.spawn(|| *val.borrow());
    });
}
Run Code Online (Sandbox Code Playgroud)

在完整的代码中,我使用的是一种RefCell嵌入其中的类型(a typed_arena::Arena).我正在使用crossbeam来确保线程不会超过它所引用的引用.

这会产生错误:

error: the trait bound `std::cell::RefCell<i32>: std::marker::Sync` is not satisfied [E0277]

    scope.spawn(|| *val.borrow());
          ^~~~~
Run Code Online (Sandbox Code Playgroud)

我相信我理解为什么会发生这样的错误:RefCell不是设计为从多个线程同时调用,并且因为它使用内部可变性,所以需要单个可变借位的正常机制不会阻止多个并发操作.这甚至记录在Sync:

不属于类型Sync是那些具有"室内易变性"在非线程安全的方式,比如CellRefCellstd::cell.

这一切都很好,但在这种情况下,我知道只有一个线程能够访问RefCell.我怎样才能向编译器确​​认我理解我在做什么,我确保是这样的?当然,如果我认为这实际上是安全的是不正确的,我会非常乐意被告知原因.

unsafe thread-safety rust

6
推荐指数
2
解决办法
1138
查看次数

标签 统计

rust ×2

thread-safety ×1

unsafe ×1