Понимание последовательности выпуска и синхронизации с в C11 - PullRequest
1 голос
/ 12 апреля 2019

Я пытаюсь понять модель памяти и читает 5.1.2.4 Multi-threaded executions and data races и смущен концепцией последовательности выпуска, определенной в 5.1.2.4(p10) следующим образом:

Последовательность выпуска, возглавляемая операцией освобождения A для атомарного объекта M - это максимальная непрерывная подпоследовательность побочных эффектов в порядке модификации M, где первая операция - A, и каждая последующая операция выполняется тем же потоком, который выполнилrelease или является атомарной операцией чтения-изменения-записи.

, которая впоследствии используется для определения синхронизации с 5.1.2.4(p11) следующим образом:

Некоторые вызовы библиотеки синхронизируются сдругие вызовы библиотеки, выполняемые другим потоком.В частности, атомарная операция A, которая выполняет операцию освобождения для объекта M, синхронизируется с атомарной операцией B, которая выполняет операцию получения для M и считывает значение, записанное любым побочным эффектом в последовательности выпуска.во главе с A.

Я могу представить себе следующий пример:

#include <stdatomic.h>
Atomic_ int a; // <<--- M

int main(void){
    atomic_store_explicit(&a, 42, memory_order_release); // <<--- A
    atomic_store_explicit(&a, 442, memory_order_release); 
    atomic_store_explicit(&a, 242, memory_order_release); 
    int a_value = atomic_load_explicit(&a, memory_order_acquire);
    atomic_store_explicit(&a, 242, memory_order_release);
}

В настоящее время я понимаю его как A, являющийся atomic_store_explicit(&a, 42, memory_order_release);, и его последовательность выпуска

atomic_store_explicit(&a, 442, memory_order_release); 
atomic_store_explicit(&a, 242, memory_order_release); 

Но atomic_store_explicit(&a, 242, memory_order_release); не включен, поскольку за ним следует int a_value = atomic_load_explicit(&a, memory_order_acquire);, который является операцией получения.

Теперь перейдем к synchronize with атомарной операции A, которая выполняетоперация освобождения объекта M синхронизируется с атомарной операцией B, которая выполняет операцию получения для M и считывает значение, записанное любым побочным эффектом в последовательности освобождения, возглавляемой A. означает, что все операции освобождения в последовательности освобожденияA видны при операции получения, которая atomic_load_explicit(&a, memory_order_acquire);

Это правильно, или я что-то пропустил?

1 Ответ

3 голосов
/ 12 апреля 2019

Нет, последовательность включает все четыре операции сохранения, поскольку операция промежуточной загрузки выполняется одним и тем же потоком.В основном для вашего примера вам не нужно ссылаться на синхронизацию.Поскольку в игре есть только одна тема, «последовательность перед» уже дает вам всю необходимую информацию.Оптимизатор может даже пропустить все хранилища, кроме последнего в вашем упрощенном примере, даже для атомарных операций.(Ну, в спецификации atomic_store есть volatile, но давайте пока что забудем об этом.)

Думаю, идея концепции последовательности выпуска заключается в определении точек накоторые считывают разные потоки, могут перехватывать сохраненные значения и которые упорядочивают чтение по порядку после первой операции сохранения в последовательности.При этом тот факт, что поток читает записанное им значение, можно игнорировать.

...