简体   繁体   English

在 rust 中读取具有多个线程的文件是否被视为未定义行为?

[英]Is reading from a file with multiple threads considered undefined behavior in rust?

Example seen below.示例见下。 It seems like this might by definition be ub, but it remains unclear to me.从定义上看,这似乎可能是 ub,但我仍然不清楚。

fn main(){
  let mut threads = Vec::new();

  for _ in 0..100 {
    let thread = thread::spawn(move || {
      fs::read_to_string("./config/init.json")
     .unwrap()
      .trim()
      .to_string()
    });
    threads.push(thread);
  }

  for handler in threads {
   handler.join().unwrap();
  }
}

On most operating systems only individual read operations are guaranteed to be atomic.在大多数操作系统上,只有单独的read操作可以保证是原子的。 read_to_string may perform multiple distinct reads, which means that it's not guaranteed to be atomic between multiple threads/processes. read_to_string可以执行多个不同的读取,这意味着它不能保证在多个线程/进程之间是原子的。 If another process is modifying this file concurrently, read_to_string could return a mixture of data from before and after the modification.如果另一个进程同时修改此文件, read_to_string可能会返回修改前后的混合数据。 In other words, each read_to_string operation is not guaranteed to return an identical result, and some may even fail while others succeed if another process deletes the file while the program is running.换句话说,每个read_to_string操作都不能保证返回相同的结果,如果另一个进程在程序运行时删除文件,有些甚至可能会失败,而另一些会成功。

However, none of this behavior is classified as "undefined."但是,这些行为都没有被归类为“未定义”。 Absent hardware problems, you are guaranteed to get back a std::io::Result<String> in a valid state, which is something you can reason about.如果没有硬件问题,您可以保证在有效的 state 中取回std::io::Result<String> ,这是您可以推理的。 Once UB is invoked, you can no longer reason about the state of the program.一旦 UB 被调用,就无法再推理程序的 state。

By way of analogy, consider a choose your own adventure book.以此类推,考虑选择一本自己的冒险书。 At the end of each segment you'll have some instructions like "If you choose to go into the cave, go to page 53. If you choose to take the path by the river, go to page 20."在每个部分的末尾,您将有一些说明,例如“如果您选择 go 进入洞穴,go 到第 53 页。如果您选择走河边的路径,Z34D1F91FB2E514B8576ZB 到第 53 页。”5A89A6ZB 到第 53 页。 Then you turn to the appropriate page and keep reading.然后您转到相应的页面并继续阅读。 This is a bit like Result -- if you have an Ok you do one thing, but if you have an Err you do another thing.这有点像Result ——如果你有一个Ok你做一件事,但如果你有一个Err你做另一件事。

Once undefined behavior is invoked, this kind of choice no longer makes sense because the program is in a state where the rules of the language no longer apply.一旦调用了未定义的行为,这种选择就不再有意义,因为程序位于 state 中,语言规则不再适用。 The program could do anything, including deleting random files from your hard drive.该程序可以做任何事情,包括从硬盘中删除随机文件。 In the book analogy, the book caught fire.在书的类比中,这本书着火了。 Trying to follow the rules of the book no longer makes any sense, and you hope the book doesn't burn your house down with it.试图遵循这本书的规则不再有任何意义,你希望这本书不会烧毁你的房子。

In Rust you're not supposed to be able to invoke UB without using the unsafe keyword, so if you don't see that keyword anywhere then UB isn't on the table.在 Rust 中,如果不使用unsafe关键字,您不应该能够调用 UB,因此如果您在任何地方都看不到该关键字,则 UB 不在桌面上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM