gpt4 book ai didi

multithreading - 在线程之间发送数据的惯用方法是什么?

转载 作者:行者123 更新时间:2023-12-04 06:38:15 24 4
gpt4 key购买 nike

我想在单独的线程中进行一些计算,然后从主线程中恢复数据。在 Rust 中将一些数据从一个线程传递到另一个线程的规范方法是什么?

fn main() {
let handle = std::thread::spawn(|| {
// I want to send this to the main thread:
String::from("Hello world!")
});

// How to recover the data from the other thread?

handle.join().unwrap();
}

最佳答案

有很多方法可以在线程之间发送数据——没有一个明确的“最佳”解决方案。这取决于你的情况。

仅使用 thread::join
很多人没有意识到,您只需使用 thread 就可以非常轻松地发送数据。 API,但只有两次:一次到新线程,一次返回。

use std::thread;

let data_in = String::from("lots of data");
let handle = thread::spawn(move || {
println!("{}", data_in); // we can use the data here!

let data_out = heavy_compuations();
data_out // <-- simply return the data from the closure
});

let data_out = handle.join().expect("thread panicked :(");
println!("{}", data_out); // we can use the data generated in the thread here!

( Playground )

这对于刚刚产生以完成一项特定工作的线程非常有用。请注意 move闭包之前的关键字,确保所有引用的变量都移动到闭包中(然后移动到另一个线程)。

来自 std 的 channel

标准库提供了 multi producer single consumer channel in std::sync::mpsc .您可以通过一个 channel 发送任意多个值,因此可以在更多情况下使用。简单的例子:

use std::{
sync::mpsc::channel,
thread,
time::Duration,
};

let (sender, receiver) = channel();
thread::spawn(move || {
sender.send("heavy computation 1").expect("receiver hung up :(");
thread::sleep(Duration::from_millis(500));
sender.send("heavy computation 2").expect("receiver hung up :(");
});

let result1 = receiver.recv().unwrap();
let result2 = receiver.recv().unwrap();

( Playground )

当然,您也可以创建另一个 channel 来提供另一个方向的通信。

更强大的 channel 来自 crossbeam
不幸的是,标准库目前仅提供仅限于单个使用者的 channel (即 Receiver 无法克隆)。要获得更强大的 channel ,您可能需要使用 channels from the awesome crossbeam library .他们的描述:

This crate is an alternative to std::sync::mpsc with more features and better performance.



特别是,它是一个 mpmc(多消费者!) channel 。这提供了一种在多个线程之间轻松共享工作的好方法。例子:

use std::thread;

// You might want to use a bounded channel instead...
let (sender, receiver) = crossbeam_channel::unbounded();
for _ in 0..num_cpus::get() {
let receiver = receiver.clone(); // clone for this thread
thread::spawn(move || {
for job in receiver {
// process job
}
});
}

// Generate jobs
for x in 0..10_000 {
sender.send(x).expect("all threads hung up :(");
}

( Playground )

同样,添加另一个 channel 允许您将结果传送回主线程。

其他方法

还有很多其他的 crate 提供了在线程之间发送数据的其他方法。太多了,无法在此一一列出。

请注意,发送数据并不是线程间通信的唯一方式。还可以通过 Mutex 在线程之间共享数据, atomics 、无锁数据结构等多种方式。这在概念上是非常不同的。这取决于具体情况,发送或共享数据是描述跨线程通信的更好方式。

关于multithreading - 在线程之间发送数据的惯用方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59075477/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com