gpt4 book ai didi

rust - 如何从 Rust 中的不同线程写入文件?

转载 作者:行者123 更新时间:2023-12-03 11:27:53 24 4
gpt4 key购买 nike

我试图找到一种方法来锁定不同线程中的文件写入。正确的做法是什么?由于性能原因,当我需要写东西时,我不想一直打开和关闭文件。
我试过的代码是:

use std::{fs, mem, thread};
use std::os::unix::prelude::FileExt;
use std::sync::{Arc, Mutex};


const COUNT: usize = 1000;


fn main() {
let file: fs::File = fs::File::create("foo.txt").unwrap();

let v: [u32; COUNT] = [6; COUNT];

let counter = Arc::new(Mutex::new(0));

let mut threads = Vec::new();
for _ in 0..COUNT {
let counter = Arc::clone(&counter);

let thread = thread::spawn(move || {
let mut i = counter.lock().unwrap();

let offset = (mem::size_of::<u32>() * (*i)) as u64;
let bytes = unsafe { mem::transmute::<u32, [u8; 4]>(v[*i]) };
file.write_all_at(&bytes, offset).unwrap();

*i += 1;
});
threads.push(thread);
}

for thread in threads {
thread.join().unwrap();
}
}
它给出了错误:
move occurs because `file` has type `std::fs::File`, which does not implement the `Copy` trait
据我了解,文件对象不能在线程之间轻松共享。我想,我在关于这个问题的整个方法中做错了。那么从 Rust 中的不同线程写入文件的正确方法是什么?

最佳答案

您可以将文件包装在 Arc 中和一个 Mutex ,这将允许它在线程之间共享,并且一次被一个线程改变:

fn main() {
let file = Arc::new(Mutex::new(File::create("foo.txt").unwrap()));

let v: [u32; COUNT] = [6; COUNT];

let counter = Arc::new(Mutex::new(0));

let mut threads = Vec::new();
for _ in 0..COUNT {
let counter = Arc::clone(&counter);
let file = Arc::clone(&file);

let thread = thread::spawn(move || {
let mut i = counter.lock().unwrap();
let file = file.lock().unwrap();

let offset = (mem::size_of::<u32>() * (*i)) as u64;
let bytes = unsafe { mem::transmute::<u32, [u8; 4]>(v[*i]) };
file.write_all_at(&bytes, offset).unwrap();

*i += 1;
});
threads.push(thread);
}

for thread in threads {
thread.join().unwrap();
}
}
注意 std::os::unix::fs::FileExt中的读写方法对 self 进行不可变引用.这意味着上面的代码可以在没有 Mutex 的情况下编译,因为并发是由操作系统内核管理的。但是,结果是不确定的,因为多个线程可能会尝试同时写入文件,这可能不是您想要的。

关于rust - 如何从 Rust 中的不同线程写入文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65235821/

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