如何解决将带有引用的迭代器移动到线程中
我有一个代表文件的类型。为简单起见,假设该类型包含一个包含文件内容的缓冲区。
还有一种方法可以构建一个迭代器,它保存对内部缓冲区的引用。
文件类型是在主线程上创建的,但我需要将迭代器“发送”到线程中。
让我展示我想要做什么
struct FileType {...}
let mut my_file_type = FileType::new("some_filename");
let mut my_iterator = my_file_type.iter();
external_library_object.start_process(move|_| {
for _ in (0..10) {
println!(my_iterator.next().unwrap());
}
}
external_library_object
(顺便说一下是 cpal 的设备)是……嗯,我无法更改的库中的对象。闭包参数实现了 Send trait。
这不起作用,因为 my_file_type
的寿命不够长。
所以我尝试了 Mutex(所以迭代器是可变的)和 Arc(所以我们在 2 个线程之间共享迭代器)的组合
...
let mut my_file_type = FileType::new("some_filename");
let mut my_iterator = Arc::new(Mutex::new(my_file_type.iter()));
external_library_object.start_process(move|_| {
let mut cloned = my_iterator.clone();
for _ in (0..10) {
println!(cloned.lock().unwrap().next().unwrap());
}
}
但同样,这不起作用。我收到类似这样的错误:
xx | let mut my_iterator = Arc::new(Mutex::new(my_file_type.iter()));
| ^^^^^^^^^^^^-------
| |
| borrowed value does not live long enough
| argument requires that `my_file_type` is borrowed for `'static`
...
xx | }
| - `my_file_type` dropped here while still borrowed
我有点卡在这里。有没有办法使用迭代器,该迭代器在不同的线程中引用了其他对象(在本例中为缓冲区)?
编辑:在我的特定情况下,迭代器是无限的,闭包执行多次。这就是我无法在线程内移动整个 FileType 的原因。
解决方法
这很棘手,因为进程借用了一个迭代器,而迭代器又借用了一个结构体。仅将迭代器放入 Arc<Mutex<>>
是不够的,因为该指针可能仍然比它借用的 FileType
更有效。但是,我们不能将 FileType
和迭代器都放入引用计数结构中,因为该结构将是自引用的。
我能想到的最简单的解决方案(不使用 scoped threads)是创建一个 拥有 FileType
的迭代器,然后将它放入Arc<Mutex<>>
(minimal playground example):
let my_file_type = FileType::new("test!");
let my_iterator = Arc::new(Mutex::new(my_file_type.into_iter()));
external_library_object.start_process(move |_| {
for _ in 0..10 {
println!("{:?}",my_iterator.lock().unwrap().next().unwrap());
}
});
您只需要为您的 FileType
结构实现一个拥有的迭代器(如果它还不存在)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。