Разрешает ли правило «как если бы» такое изменение порядка выполнения
Как мы знаем, компилятор или ЦП могут изменить порядок выполнения по своему усмотрению, только если они следуют правилу «как если бы». Например, если у нас есть такой кусок кода:
C = A + B;
D = E + F;
Компилятор или ЦП могут выполнять
D = E + F
перед
C = A + B
. Я могу понять, что.
А теперь поговорим о другом случае.
Сказать, что у меня две темы и. Я хочу установить несколько отметок во время выполнения, чтобы я мог контролировать весь процесс
a
и
b
.
queue q; // thread safe
void thread_a()
{
// do something
q.push("a - 1");
// do something
q.push("a - 2");
}
void thread_b()
{
// do something
q.push("b - 1");
// do something
q.push("b - 2");
}
Мой вопрос: поскольку у нас есть правило «как если бы» и порядок выполнения можно изменить, значит ли это, что сообщения в нем ненадежны? Это означает, что реальный порядок выполнения, но в
q
Там может быть
a - 1
,
a - 2
,
b - 1
и
b - 2
? Если это могло произойти, как мне разработать или какие технические средства мне следует использовать для отслеживания процесса многопоточности?
1 ответ
Reordering and multithreading are 2 different things:
Via multi threading, possible outputs are:
- , , ,
- , , ,
- , , ,
- , , ,
- , , ,
-
"b - 1"
,"a - 1"
,"a - 2"
,"b - 2"
You just have the guaranty that "a - 1" comes before "a - 2", and "b - 1" comes before "b - 2". (unrelated to reordering)
Reordering with the as-if rule is just an optimization.
as_if states:
The C++ compiler is permitted to perform any changes to the program as long as the following remains true:
- Accesses (reads and writes) to volatile objects occur strictly according to the semantics of the expressions in which they occur. In particular, they are not reordered with respect to other volatile accesses on the same thread.(since C++11)
- At program termination, data written to files is exactly as if the program was executed as written.
- Prompting text which is sent to interactive devices will be shown before the program waits for input.
- If the ISO C pragma #pragma STDC FENV_ACCESS is supported and is set to ON, the changes to the floating-point environment (floating-point exceptions and rounding modes) are guaranteed to be observed by the floating-point arithmetic operators and function calls as if executed as written, except thatthe result of any floating-point expression other than cast and assignment may have range and precision of a floating-point type different from the type of the expression (see FLT_EVAL_METHOD)notwithstanding the above, intermediate results of any floating-point expression may be calculated as if to infinite range and precision (unless #pragma STDC FP_CONTRACT is OFF)
Your code (except potentially the
// do something
) does nothing of that, so it can even drop the 2 code completely, push "c - 1".
But if after you print queue content, then the content should be one of the 6 shown above.