向量(或向量的向量)上的并发操作
Concurrent operations on a Vector (or Vector of Vectors)
我即将编写一个 Rust 程序,我想在其中实现并发。我的数据将存储在一个 Vector 或 Vector of Vectors 中,以我能使工作最简单的方式为准。下面是一些伪代码,用于显示如何设置结构和向量。显然语法不正确。
struct Artifact
identifier = "abc123";
vector_containing_Line_structs = [struct Line, struct Line, struct Line, ..., etc];
// ^ this vector will contain thousands of line structs
struct Line
line_type = 1
speed = 5
array_length = 4;
array = {10, 20, 30, 40}
基本上,这就是我目前正在考虑的存储数据的方式(对想法持开放态度)。在程序的后面,我想使用多线程并发地对 vector_containing_Line_structs
向量的子集执行计算。 Thread1 在索引 0-10000 上运行,thread2 在索引 10001-20000 上运行,等等。线程是只读的,它们不会将任何内容写回 Line 结构,只是访问数组和每个结构中的结构 'variables' .
rust 编译器会让不同的线程同时操作同一个 vector 中的项目吗?或者,有没有一种方法可以拆分这些数据,以便以保留 order/indexing 并允许以类似方式进行并发计算的方式组织它?
-- 我唯一的另一个想法是向量的向量。 vector some_vector = [ [10k Line structs], [10k Line Structs], ... ]
。我希望 Rust 让我将每个子向量分配给不同的线程。
由于您的问题不是特定于结构的成员,而是关于跨多个线程从共享向量读取数据的能力,
这是一个处理简单整数向量的简单示例。
不能将引用或切片直接传递给线程,因为编译器无法证明引用的数据比线程的寿命更长。
然后我们使用 Arc
只要线程存在就会使这些数据保持活动状态。
从线程中获取部分结果通常使用 mpsc
channel。
fn main() {
// prepare vector to be shared
let mut data = Vec::new();
for i in 0..10_000 {
data.push(i);
}
// make it accessible to multiple threads
let data = std::sync::Arc::new(data);
// prepare communication channel
let (tx, rx) = std::sync::mpsc::channel();
// launch the desired number of threads
let thread_count = 8;
let mut threads = Vec::new();
for idx in 0..thread_count {
// clone shared ressources in order to move them into the thread
let tx = tx.clone();
let data = data.clone();
threads.push(std::thread::spawn(move || {
// determine the part of shared data to be accessed by this thread
let begin = data.len() * idx / thread_count;
let end = data.len() * (idx + 1) / thread_count;
let slc = &data[begin..end];
// work on this slice
let mut sum = 0;
for v in slc {
sum += v;
}
println!("thread {} --> {}", idx, sum);
// send a result to main thread
tx.send(sum).unwrap();
}));
}
// wait for threads and collect results
let mut result = 0;
for th in threads {
result += rx.recv().unwrap();
th.join().unwrap();
}
println!("done: {}", result);
}
我即将编写一个 Rust 程序,我想在其中实现并发。我的数据将存储在一个 Vector 或 Vector of Vectors 中,以我能使工作最简单的方式为准。下面是一些伪代码,用于显示如何设置结构和向量。显然语法不正确。
struct Artifact
identifier = "abc123";
vector_containing_Line_structs = [struct Line, struct Line, struct Line, ..., etc];
// ^ this vector will contain thousands of line structs
struct Line
line_type = 1
speed = 5
array_length = 4;
array = {10, 20, 30, 40}
基本上,这就是我目前正在考虑的存储数据的方式(对想法持开放态度)。在程序的后面,我想使用多线程并发地对 vector_containing_Line_structs
向量的子集执行计算。 Thread1 在索引 0-10000 上运行,thread2 在索引 10001-20000 上运行,等等。线程是只读的,它们不会将任何内容写回 Line 结构,只是访问数组和每个结构中的结构 'variables' .
rust 编译器会让不同的线程同时操作同一个 vector 中的项目吗?或者,有没有一种方法可以拆分这些数据,以便以保留 order/indexing 并允许以类似方式进行并发计算的方式组织它?
-- 我唯一的另一个想法是向量的向量。 vector some_vector = [ [10k Line structs], [10k Line Structs], ... ]
。我希望 Rust 让我将每个子向量分配给不同的线程。
由于您的问题不是特定于结构的成员,而是关于跨多个线程从共享向量读取数据的能力, 这是一个处理简单整数向量的简单示例。
不能将引用或切片直接传递给线程,因为编译器无法证明引用的数据比线程的寿命更长。
然后我们使用 Arc
只要线程存在就会使这些数据保持活动状态。
从线程中获取部分结果通常使用 mpsc
channel。
fn main() {
// prepare vector to be shared
let mut data = Vec::new();
for i in 0..10_000 {
data.push(i);
}
// make it accessible to multiple threads
let data = std::sync::Arc::new(data);
// prepare communication channel
let (tx, rx) = std::sync::mpsc::channel();
// launch the desired number of threads
let thread_count = 8;
let mut threads = Vec::new();
for idx in 0..thread_count {
// clone shared ressources in order to move them into the thread
let tx = tx.clone();
let data = data.clone();
threads.push(std::thread::spawn(move || {
// determine the part of shared data to be accessed by this thread
let begin = data.len() * idx / thread_count;
let end = data.len() * (idx + 1) / thread_count;
let slc = &data[begin..end];
// work on this slice
let mut sum = 0;
for v in slc {
sum += v;
}
println!("thread {} --> {}", idx, sum);
// send a result to main thread
tx.send(sum).unwrap();
}));
}
// wait for threads and collect results
let mut result = 0;
for th in threads {
result += rx.recv().unwrap();
th.join().unwrap();
}
println!("done: {}", result);
}