从多个线程write到同一文件

问题描述 投票:0回答:1

是否从多个线程线程安全地写入同一文件?这是我编写的示例代码,截至目前,文件的内容是混合输入数据。如果它不是线程安全的,是否有线程安全的方法可以使用内置模块或任何外部板条箱来执行此操作,而不是我处理排他性。

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(); }
    
multithreading file rust
1个回答
0
投票
为您的“最后一个线程获胜”线程安全要求,我建议写入临时文件并将文件重命名为最终位置。这具有以下优点:

    螺纹安全和过程安全
  • 您永远不会观察到部分书面数据
  • 在创建文件时,您永远无法观察到它缺少(至少在POSIX系统上,
  • 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(()) }

Playground

注意,我修改了用

write_all()

而不是
write()
编写的代码,因为
write()
可以写出比给出的数据更少的数据。它还返回结果而不是惊慌。
    

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.