我正在设计一个为我运行闭包的小结构,我可以将它们设置为停止:
pub fn run(&self, f: Box<dyn Fn()>) {
let should_continue = self.should_continue.clone();
self.run_thread = Some(std::thread::spawn(move || {
while should_continue.load(Ordering::Relaxed) {
//f should run fast so `should_continue` is readed frequently
f();
}
}));
}
如您所见,我在一个盒子中传递了Fn
,这给我一个关于Box无法在线程之间共享的错误。实际上,一旦将fn传递给函数run
,我就不在乎了,所以我想将闭包移至该函数,因为我将不再使用它。我无法将Fn
标记为send,因为我实际上要传递的f
没有实现Send
。那么,如何才能完全移动闭合件?
//move this closure to inside of run
self.run(||{});
最佳答案
so here's what I understand of your code具有可构建的复制用例,而不是具有随机未提供的依赖关系的代码是有用的。
我得到的错误是,不能在线程之间将dyn Fn
发送给,这与共享的截然不同:尽管有很多事情不能在线程之间共享(Sync
)(它们只能在一个线程上使用一次)还有所有必须始终保留在其原始线程上的东西。例如,Rc
并不是Send
,因为它不是将线程Rc
发送到另一个线程的线程安全的引用计数指针,这会破坏其保证,因此这是不允许的。dyn Fn
是不透明的,除了可以被多次调用之外,不对它在内部的操作提供任何真正的保证。因此就编译器而言,它可能会关闭不是Send
的内容(例如对!Sync
类型或Rc
的引用...),这意味着编译器会假定Fn
也不是Send
。
解决方案很简单:只需定义f: Box<dyn Fn() + Send>
,就可以在run
中以这种方式保证实际上可以在线程之间发送该函数;并且run
的调用者在尝试发送无法发送的函数时将收到错误消息。
demorun_ok
使用一个简单的闭包,将其发送过来没有问题。 run_not_ok
关闭了Rc
,因此该函数无法编译(只需取消注释即可查看)。 run_ok2
与run_not_ok
的功能相同,但使用Arc
代替Rc
,并且可以正常编译。
关于rust - 如何永久关闭瓶盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64151389/