Concurrency 什么';将输出'io::Write'传递给使用线程的函数的最佳方法是什么?
我尝试编写一个函数,该函数将Concurrency 什么';将输出'io::Write'传递给使用线程的函数的最佳方法是什么?,concurrency,rust,Concurrency,Rust,我尝试编写一个函数,该函数将io::write作为参数,以便输出二进制数据。现在棘手的部分是,函数在内部使用一个线程来生成数据(我知道在下面的代码中使用线程是没有意义的——它只是为了演示) 目前,我有不同的方法: 1. 这是我首选的进程的签名,但没有编译,因为w的生存期(对于编译器)似乎比线程的生存期短 3. fn过程(w:Arc){ 线程::生成(移动| |{ 让mut w=w.lock().unwrap(); 写!(w,“你好,世界”)。展开(); }).join().unwrap(); }
io::write
作为参数,以便输出二进制数据。现在棘手的部分是,函数在内部使用一个线程来生成数据(我知道在下面的代码中使用线程是没有意义的——它只是为了演示)
目前,我有不同的方法:
1.
这是我首选的进程的签名
,但没有编译,因为w
的生存期(对于编译器)似乎比线程的生存期短
3.
fn过程(w:Arc){
线程::生成(移动| |{
让mut w=w.lock().unwrap();
写!(w,“你好,世界”)。展开();
}).join().unwrap();
}
fn main(){
让buffer=Arc::new(Mutex::new(Vec::new()作为Vec));
进程(buffer.clone());
}
这是可行的,但是进程
的签名公开了使用线程的内部实现细节。我希望避免这种设计,因为在以后的版本中,线程可能会消失
有人有更好的解决方案吗?非常感谢。您可以先将W的所有权传递给函数,然后传递给线程,再传递回调用范围
fn process<W>(mut w: W) -> W where W: io::Write + Send + 'static {
thread::spawn(move || {
write!(w, "hello world").unwrap();
w
}).join().unwrap()
}
fn main() {
let output = Vec::new();
let output = process(output);
let output = process(output);
}
fn进程(mut w:w)->w其中w:io::Write+Send+'静态{
线程::生成(移动| |{
写!(w,“你好,世界”)。展开();
W
}).join().unwrap()
}
fn main(){
让output=Vec::new();
让输出=过程(输出);
让输出=过程(输出);
}
同步约束是不必要的,因此我将其删除。根据实际程序的体系结构,您可能需要使用:
外部板条箱横梁;
使用std::io;
fn进程(w:&mut w),其中w:io::Write+Send{
横梁::范围(|范围|{
范围.繁殖(| |{
写!(w,“你好,世界”)。展开();
});
});
}
fn main(){
让mut buffer=Vec::new();
进程(&mut缓冲区);
}
使用crosseam,可以生成可以保存非静态引用的线程。可以保证这些线程将超过捕获的引用,因为当
crossbeam::scope()
函数退出时,所有线程都是隐式连接的。因此,使用横梁可以省略W
上的静态
和同步
边界,并在线程闭包中使用&mut W
引用。谢谢,这就解决了问题。仍然不是我的首选界面,但我想这是我们能做的最好的了。crossbeam
不是我的项目的选项,但你是对的,它解决了我的示例代码。谢谢你!
fn process<W>(w: &mut W) where W: io::Write + Send + Sync + 'static {
thread::spawn(move || {
write!(w, "hello world").unwrap();
}).join().unwrap();
}
fn main() {
let output = Vec::new();
process(&mut output);
}
fn process(w: Arc<Mutex<io::Write + Send>>) {
thread::spawn(move || {
let mut w = w.lock().unwrap();
write!(w, "hello world").unwrap();
}).join().unwrap();
}
fn main() {
let buffer = Arc::new(Mutex::new(Vec::new() as Vec<u8>));
process(buffer.clone());
}
fn process<W>(mut w: W) -> W where W: io::Write + Send + 'static {
thread::spawn(move || {
write!(w, "hello world").unwrap();
w
}).join().unwrap()
}
fn main() {
let output = Vec::new();
let output = process(output);
let output = process(output);
}
extern crate crossbeam;
use std::io;
fn process<W>(w: &mut W) where W: io::Write + Send {
crossbeam::scope(|scope| {
scope.spawn(|| {
write!(w, "hello world").unwrap();
});
});
}
fn main() {
let mut buffer = Vec::new();
process(&mut buffer);
}