Kir*_*kov 2 multithreading thread-safety rust
我是 Rust 新手,来自 JS。所以我的线程有问题。
我想尝试加快我的程序速度,但我不明白如何发送我的批次来运行。
fn read_lines(reader: BufReader<File>) -> Vec<JoinHandle<()>> {
let mut batch = vec![];
let mut children_th = vec![];
for line in reader.lines() {
let line_str = line.expect("invalid line");
if batch.len() >= BATCH_SIZE && !line_str.contains('[') {
batch.push(line_str);
children_th.push(thread::spawn(|| process_data(batch.clone())));
batch.clear();
}
}
children_th
}
fn process_data(lines: Vec<String>) {
let mut rus_word = "".to_string();
let mut definition: String = "".to_string();
let mut parsed_result: Vec<VedyDictionary> = vec![];
for line_str in lines {
if line_str.trim().chars().count() > 1 {
if !line_str.contains('[') {
if !rus_word.is_empty() {
parsed_result.push(parse_to_dictionary(rus_word, &definition));
definition = "".to_string();
}
rus_word = line_str.trim().to_string();
} else {
definition.push_str(line_str.trim());
definition.push('\n');
}
}
}
write_jsons(&parsed_result);
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下我收到此错误:
error[E0382]: borrow of moved value: `batch`
--> src/main.rs:41:12
|
36 | let mut batch = vec![];
| --------- move occurs because `batch` has type `Vec<std::string::String>`, which does not implement the `Copy` trait
...
41 | if batch.len() >= BATCH_SIZE && !line_str.contains('[') {
| ^^^^^^^^^^^ value borrowed here after move
...
44 | children_th.push(thread::spawn(move || process_data(batch.clone(), index)));
| ------- value moved into closure here, in previous iteration of loop
Run Code Online (Sandbox Code Playgroud)
我在这里找到了解决方法,但看起来很难看。我想我做错了。有人可以推荐一些东西吗?解决方法:
error[E0382]: borrow of moved value: `batch`
--> src/main.rs:41:12
|
36 | let mut batch = vec![];
| --------- move occurs because `batch` has type `Vec<std::string::String>`, which does not implement the `Copy` trait
...
41 | if batch.len() >= BATCH_SIZE && !line_str.contains('[') {
| ^^^^^^^^^^^ value borrowed here after move
...
44 | children_th.push(thread::spawn(move || process_data(batch.clone(), index)));
| ------- value moved into closure here, in previous iteration of loop
Run Code Online (Sandbox Code Playgroud)
是否可以这样做:
fn read_lines(reader: BufReader<File>) -> Vec<JoinHandle<()>> {
let mut batch = vec![];
let mut children_th = vec![];
for line in reader.lines() {
let line_str = line.expect("invalid line");
if batch.len() >= BATCH_SIZE && !line_str.contains('[') {
batch.push(line_str);
let batch_clone = batch.clone(); // clone here
children_th.push(thread::spawn(move || process_data(batch_clone))); // move cloned variable here
batch.clear();
} else {
batch.push(line_str);
}
}
children_th
}
Run Code Online (Sandbox Code Playgroud)
谢谢!
Vec我注意到您在生成新线程后立即清除了本地副本。换句话说,您希望将 的内容提供Vec给新线程并以空的 重新开始Vec。
当您在 Rust 中移动变量中的值时,该变量实际上再次变为未初始化,这意味着即使在移动它之后您也可以为其分配新值。因此,您根本不需要克隆。将本地移动Vec到新的线程闭包中,并Vec在执行此操作后分配一个新的:
batch.push(line_str);
children_th.push(thread::spawn(move || process_data(batch)));
// The batch variable is now "dead" but we can revive it by assigning
// a new value to it:
batch = vec![];
Run Code Online (Sandbox Code Playgroud)
Vec这避免了不必要的整个内容的克隆。