How do intertwined scopes create a “data race”? [duplicate]

孤街醉人 提交于 2020-05-28 06:59:20

问题


The Rust book talks about having multiple readers and multiple mutable references to an object as a data race situation that may lead to issues.

For example, this code:

fn main() {
    let mut x = 1;
    let r1 = &mut x;
    *r1 = 2;
    let r2 = &mut x;
    *r2 = 3;
    println!("{}", r1);
    println!("{}", r2);
}

will be rejected by Rust compiler because r1 and r2 scopes are intertwined.

But what is problem here? I mean, this is just one thread and there is no "reading and writing at the same time", so all these statements should be executed strictly sequentially and give deterministic reproducible result.


回答1:


From Niko Matsakis' blog:

I’ve often thought that while data-races in a technical sense can only occur in a parallel system, problems that feel a lot like data races crop up all the time in sequential systems. One example would be what C++ folk call iterator invalidation—basically, if you are iterating over a hashtable and you try to modify the hashtable during that iteration, you get undefined behavior. Sometimes your iteration skips keys or values, sometimes it shows you the new key, sometimes it doesn’t, etc.

But whatever the outcome, iterator invalidation feels very similar to a data race. The problem often arises because you have one piece of code iterating over a hashtable and then calling a subroutine defined over in some other module. This other module then writes to the same hashtable. Both modules look fine on their own, it’s only the combination of the two that causes the issue. And because of the undefined nature of the result, it often happens that the code works fine for a long time—until it doesn’t.

Rust’s type system prevents iterator invalidation.

Rust's type system disallows single-threaded programs like the one below to compile because they would result in Undefined Behavior and while that technically isn't a data race this particular error is in the same ballpark of "errors caused by two independent pieces of code mutating the same data in an interweaved fashion" so it's very similar to a data race and I believe that's what the Rust book was trying to communicate:

use std::collections::HashMap;

fn main() {
    let mut map = HashMap::new();
    map.insert(1, 1);
    map.insert(2, 2);
    map.insert(3, 3);

    for _ in map.iter() {
        map.insert(4, 4); // compile error!
    }
}

playground



来源:https://stackoverflow.com/questions/61851916/how-do-intertwined-scopes-create-a-data-race

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!