是否从多个线程线程安全地写入同一文件?这是我编写的示例代码,截至目前,文件的内容是混合输入数据。如果它不是线程安全的,是否有线程安全的方法可以使用内置模块或任何外部板条箱来执行此操作,而不是我处理排他性。
use std::io::{BufWriter, Write};
use std::path::PathBuf;
use std::fs::{File, OpenOptions};
use std::thread;
fn write_to_file(file_path: PathBuf) {
let file = OpenOptions::new()
.write(true)
.open(&file_path)
.unwrap();
let mut buf_writer = BufWriter::new(&file);
println!("{:?}", thread::current().id());
let file_str = format!("{:?}: {:?}\n", &file_path, thread::current().id());
for _ in 0..1000000 {
buf_writer.write(file_str.as_bytes()).expect(&format!("unable to write to file {}", &file_str));
}
buf_writer.flush().expect("unable to flush the file");
}
fn create_file(file_path: PathBuf) {
File::create(file_path).expect("create failed");
}
fn main() {
let file_path = PathBuf::from("/home/harry/a.txt");
create_file(file_path.clone());
let file_path1 = file_path.clone();
let file_path2 = file_path.clone();
let jh1 = thread::spawn(move || write_to_file(file_path1));
let jh2 = thread::spawn(move || write_to_file(file_path2));
let _ = jh1.join();
let _ = jh2.join();
}
rename()
是原子)
fn write_to_file(file_path: &Path) -> io::Result<()> {
let mut tmp_path = file_path.to_owned();
tmp_path.as_mut_os_string().push(".new");
let file = OpenOptions::new().write(true).open(&file_path)?;
let mut buf_writer = BufWriter::new(file);
println!("{:?}", std::thread::current().id());
let file_str = format!("{:?}: {:?}\n", &file_path, std::thread::current().id());
for _ in 0..1000000 {
buf_writer.write_all(file_str.as_bytes())?;
}
buf_writer.flush()?;
std::fs::rename(tmp_path, file_path)?;
Ok(())
}
注意,我修改了用write_all()
而不是
write()
编写的代码,因为
write()
可以写出比给出的数据更少的数据。它还返回结果而不是惊慌。