rust 利用rayon ceate 实现多线程
例子1
use std::collections::HashMap;
use rayon::prelude::*;
use std::fs::File;
use std::io::{self, BufRead};
fn main() -> io::Result<()> {
let filenames = vec!["file1.txt", "file2.txt", "file3.txt", "file4.txt"]; // 你的文件名列表
let mut file_contents: HashMap<String, String> = HashMap::new();
filenames.par_iter().for_each(|filename| {
if let Ok(file) = File::open(filename) {
let reader = io::BufReader::new(file);
let lines: Vec<_> = reader
.lines()
.map(|line| line.unwrap_or_else(|e| e.to_string()))
.collect();
let content = lines.join("\n");
file_contents.insert(filename.to_string(), content);
}
});
// 现在你有一个包含文件名和文件内容的哈希表
for (filename, content) in &file_contents {
println!("File: {}\n{}", filename, content);
}
Ok(())
}
首先创建一个空的HashMap,其中文件名作为键,文件内容作为值。然后,我们使用par_iter().for_each()并行地读取文件并将内容插入哈希表中。最后,我们遍历哈希表以打印文件名和内容。
请注意,如果多个线程尝试同时插入哈希表,你需要确保在插入操作上进行适当的同步,以避免竞态条件。在上面的示例中,由于每个线程处理不同的文件,因此没有并发插入相同的键,因此不需要额外的同步。但如果你的需求更复杂,需要并发插入相同的键,你可能需要使用Mutex等同步机制来确保线程安全
例子2
对file_contents哈希表加锁,确保同一时间只有一个线程修改它。
use std::collections::HashMap;
use rayon::prelude::*;
use std::fs::File;
use std::io::{self, BufRead};
use std::sync::{Arc, Mutex};
fn main() -> io::Result<()> {
let filenames = vec!["file1.txt", "file2.txt", "file3.txt", "file4.txt"]; // 你的文件名列表
let file_contents: Arc<Mutex<HashMap<String, String>>> = Arc::new(Mutex::new(HashMap::new()));
filenames.par_iter().for_each(|filename| {
if let Ok(file) = File::open(filename) {
let reader = io::BufReader::new(file);
let lines: Vec<_> = reader
.lines()
.map(|line| line.unwrap_or_else(|e| e.to_string()))
.collect();
let content = lines.join("\n");
// 使用 Mutex 来保护哈希表的插入操作
let mut table = file_contents.lock().unwrap();
table.insert(filename.to_string(), content);
}
});
// 现在你有一个包含文件名和文件内容的哈希表,它是线程安全的
let table = file_contents.lock().unwrap();
for (filename, content) in table.iter() {
println!("File: {}\n{}", filename, content);
}
Ok(())
}
例子3
rust 多线程读取超大文件
use std::fs::File;
use std::io::{self, BufRead, BufReader};
use rayon::prelude::*;
// Function to read a file
fn read_file(filename: &str) -> io::Result<BufReader<File>> {
let file = File::open(filename)?;
Ok(BufReader::new(file))
}
let target_word = "ERROR";
let reader = read_file("large_file.txt").expect("Could not read file");
let error_count: usize = reader
.lines()
.filter_map(Result::ok)
.par_bridge()
.filter(|line| {
line.contains(target_word) // This is a stand in for expensive line processing
})
.count();
println!("Number of error logs: {}", error_count);
网友评论