Does this example contain a data race?

馋奶兔 提交于 2019-12-06 03:54:41

The C++ standard defines a data race (which triggers undefined behavior) as:

§ 1.10.1-2 [intro.races]
Two expression evaluations conflict if one of them modifies a memory location (..) and the other one reads or modifies the same memory location.

Per the C++ memory model rules, your first code fragment contains no data race because the C++ standard forbids compiler transformations that would introduce such a race:

§ 1.10.1-21 [intro.races]
Compiler transformations that introduce assignments to a potentially shared memory location that would not be modified by the abstract machine are generally precluded by this International Standard, since such an assignment might overwrite another assignment by a different thread in cases in which an abstract machine execution would not have encountered a data race.

So it says that if the condition in the if-statement (x) yields false, no transformation is allowed that would modify y, even if the end result is that y appears unmodified.

The second example clearly contains a data race because 2 threads can write and read x at the same time (same applies to y).

Note that both C++ and C have a memory model since version 11. If you use a compiler that does not support C11, multithreaded behavior is not officially defined.

Here is a question that shows an example of an illegal compiler transformation.

//CODE-1: initially, x == 0 and y == 0
if (x) y++; // pthread 1
if (y) x++; // pthread 2

There is no undefined behavior because neither x nor y will ever change their value.
However, there is still a race condition, because there is no defined sequence between read access in one thread and write access in the other one.

//CODE-2
y++; if (!x) y--; // pthread 1
x++; if (!y) x--; // pthread 2

Now you have a data race and undefined behavior because there is no sequence between y++ in thread 1 and if(!y) in thread 2 and vice versa. So possible results for y are:

  • y = 0
    Thread 1 runs after thread 2. So x is still 0.
  • y = 1
    Thread 1 runs in parallel to thread 2, sees the change to x but not vice versa. So y is not decremented.

This has nothing to do with the memory model. It is just a race in any unsynchronized context.

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