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);
}