Класс QAtomicPointer
шаблон <typename T> class QAtomicPointerКласс QAtomicPointer — это шаблонный класс, предоставляющий платформенно-независимые атомарные операции над указателями. Подробнее...
| Заголовок: | #include <QAtomicPointer> |
| qmake: | QT += core |
| С момента: | Qt 4.4 |
Этот класс был представлен в Qt 4.4.
Открытые функции
| QAtomicPointer(const QAtomicPointer<T> &other) | |
| QAtomicPointer(T *value = nullptr) | |
| QAtomicPointer<T> & | operator=(const QAtomicPointer<T> &other) |
| T * | fetchAndAddAcquire(qptrdiff valueToAdd) |
| T * | fetchAndAddOrdered(qptrdiff valueToAdd) |
| T * | fetchAndAddRelaxed(qptrdiff valueToAdd) |
| T * | fetchAndAddRelease(qptrdiff valueToAdd) |
| T * | fetchAndStoreAcquire(T *newValue) |
| T * | fetchAndStoreOrdered(T *newValue) |
| T * | fetchAndStoreRelaxed(T *newValue) |
| T * | fetchAndStoreRelease(T *newValue) |
| T * | loadAcquire() const |
| T * | loadRelaxed() const |
| void | storeRelaxed(T *newValue) |
| void | storeRelease(T *newValue) |
| bool | testAndSetAcquire(T *expectedValue, T *newValue) |
| bool | testAndSetOrdered(T *expectedValue, T *newValue) |
| bool | testAndSetRelaxed(T *expectedValue, T *newValue) |
| bool | testAndSetRelease(T *expectedValue, T *newValue) |
Статические открытые члены
| bool | isFetchAndAddNative() |
| bool | isFetchAndAddWaitFree() |
| bool | isFetchAndStoreNative() |
| bool | isFetchAndStoreWaitFree() |
| bool | isTestAndSetNative() |
| bool | isTestAndSetWaitFree() |
Макросы
Подробное описание
Для атомарных операций с целыми числами см. класс QAtomicInteger.
Атомарная операция — это сложная операция, которая выполняется без прерывания. Класс QAtomicPointer предоставляет атомарные функции test-and-set, fetch-and-store и fetch-and-add для указателей.
Атомарный API
Порядок памяти
QAtomicPointer предоставляет несколько реализаций атомарных функций test-and-set, fetch-and-store и fetch-and-add. Каждая реализация определяет семантику порядка памяти, которая описывает, как процессор выполняет операции доступа к памяти, окружающие атомарную инструкцию. Поскольку во многих современных архитектурах допускается выполнение операций в произвольном порядке и порядок памяти, для обеспечения корректной работы приложения на всех процессорах необходимо использовать правильную семантику.
- Relaxed — порядок памяти не определен, что позволяет компилятору и процессору свободно переупорядочивать обращения к памяти.
- Acquire — обращения к памяти, следующие за атомарной операцией (в порядке программы), не могут быть переупорядочены перед атомарной операцией.
- Release — обращения к памяти перед атомарной операцией (в порядке программы) не могут быть переупорядочены после атомарной операции.
- Ordered — сочетание семантики Acquire и Release.
Test-and-set
Если текущее значение QAtomicPointer равно ожидаемому значению, функции test-and-set присваивают новое значение QAtomicPointer и возвращают true. Если значения не совпадают, эти функции ничего не делают и возвращают false. Эта операция эквивалентна следующему коду:
if (currentValue == expectedValue) {
currentValue = newValue;
return true;
}
return false; Существует 4 функции test-and-set: testAndSetRelaxed(), testAndSetAcquire(), testAndSetRelease() и testAndSetOrdered(). См. выше для объяснения различных семантик порядка памяти.
Fetch-and-store
Атомарные функции fetch-and-store считывают текущее значение QAtomicPointer, а затем присваивают новое значение, возвращая исходное значение. Эта операция эквивалентна следующему коду:
T *originalValue = currentValue; currentValue = newValue; return originalValue;
Существует 4 функции fetch-and-store: fetchAndStoreRelaxed(), fetchAndStoreAcquire(), fetchAndStoreRelease() и fetchAndStoreOrdered(). См. выше для объяснения различных семантик порядка памяти.
END_OF_DOCUMENT_MARKERАтомарные функции fetch-and-add
Атомарные функции fetch-and-add считывают текущее значение QAtomicPointer и затем добавляют заданное значение к текущему значению, возвращая исходное значение. Эта операция эквивалентна следующему коду:
T *originalValue = currentValue; currentValue += valueToAdd; return originalValue;
Существует 4 функции fetch-and-add: fetchAndAddRelaxed(), fetchAndAddAcquire(), fetchAndAddRelease() и fetchAndAddOrdered(). Смотрите выше для объяснения различных семантик упорядочивания памяти.
Тестирование функций атомного API
Разработка независимой от платформы атомной API, которая работает на всех процессорах, является сложной задачей. API, предоставляемый QAtomicPointer, гарантированно работает атомарно на всех процессорах. Однако, поскольку не все процессоры поддерживают все операции, предоставляемые QAtomicPointer, необходимо предоставить информацию о процессоре.
Вы можете проверить во время компиляции, какие функции поддерживаются на вашем оборудовании, используя различные макросы. Эти макросы покажут, всегда ли, иногда или вообще не поддерживается конкретная операция вашим оборудованием. Макросы имеют вид Q_ATOMIC_POINTER_OPERATION_IS_HOW_NATIVE. OPERATION — это одно из TEST_AND_SET, FETCH_AND_STORE или FETCH_AND_ADD, а HOW — одно из ALWAYS, SOMETIMES или NOT. Всегда будет определён ровно один макрос на операцию. Например, если определён Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE, ни Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE, ни Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE не будут определены.
Операция, завершающаяся за постоянное время, называется свободной от ожидания. Такие операции не реализуются с помощью блокировок или циклов любого типа. Для атомных операций, которые всегда поддерживаются и являются свободными от ожидания, Qt определяет Q_ATOMIC_POINTER_OPERATION_IS_WAIT_FREE в дополнение к Q_ATOMIC_POINTER_OPERATION_IS_ALWAYS_NATIVE.
В тех случаях, когда атомная операция поддерживается только в более новых поколениях процессоров, QAtomicPointer также предоставляет возможность проверить во время выполнения, что поддерживает ваше оборудование, с помощью функций isTestAndSetNative(), isFetchAndStoreNative() и isFetchAndAddNative(). Реализации, свободные от ожидания, могут быть обнаружены с помощью функций isTestAndSetWaitFree(), isFetchAndStoreWaitFree() и isFetchAndAddWaitFree().
Ниже приведён полный список всех макросов функций для QAtomicPointer:
- Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
- Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE
- Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
- Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE
- Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
- Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
- Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE
- Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
- Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
- Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
- Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
- Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE
См. также QAtomicInteger.
Документация по функциям-членам
QAtomicPointer::QAtomicPointer(const QAtomicPointer<T> &other)
Создаёт копию other.
QAtomicPointer::QAtomicPointer(T *value = nullptr)
Создаёт QAtomicPointer с заданным значением value.
QAtomicPointer<T> &QAtomicPointer::operator=(const QAtomicPointer<T> &other)
Присваивает other этому QAtomicPointer и возвращает ссылку на этот QAtomicPointer.
T *QAtomicPointer::fetchAndAddAcquire(qptrdiff valueToAdd)
Атомарная операция fetch-and-add.
Считывает текущее значение этого QAtomicPointer и добавляет valueToAdd к текущему значению, возвращая исходное значение.
Эта функция использует семантику упорядочивания памяти acquire, которая гарантирует, что доступ к памяти, следующему за атомарной операцией (в порядке программы), не может быть переупорядочен перед атомарной операцией.
T *QAtomicPointer::fetchAndAddOrdered(qptrdiff valueToAdd)
Атомарная операция fetch-and-add.
Считывает текущее значение этого QAtomicPointer и добавляет valueToAdd к текущему значению, возвращая исходное значение.
Эта функция использует семантику упорядочивания памяти ordered, которая гарантирует, что доступ к памяти до и после атомарной операции (в порядке программы) не может быть переупорядочен.
T *QAtomicPointer::fetchAndAddRelaxed(qptrdiff valueToAdd)
Атомарная операция fetch-and-add.
Считывает текущее значение этого QAtomicPointer и добавляет valueToAdd к текущему значению, возвращая исходное значение.
Эта функция использует семантику упорядочивания памяти relaxed, оставляя компилятору и процессору свободу в переупорядочивании доступа к памяти.
T *QAtomicPointer::fetchAndAddRelease(qptrdiff valueToAdd)
Атомарная операция fetch-and-add.
Считывает текущее значение этого QAtomicPointer и добавляет valueToAdd к текущему значению, возвращая исходное значение.
Эта функция использует семантику упорядочивания памяти release, которая гарантирует, что доступ к памяти перед атомарной операцией (в порядке программы) не может быть переупорядочен после атомарной операции.
T *QAtomicPointer::fetchAndStoreAcquire(T *newValue)
Атомарная операция fetch-and-store.
Считывает текущее значение этого QAtomicPointer и присваивает ему newValue, возвращая исходное значение.
Эта функция использует семантику упорядочивания памяти acquire, которая гарантирует, что доступ к памяти, следующему за атомарной операцией (в порядке программы), не может быть переупорядочен перед атомарной операцией.
T *QAtomicPointer::fetchAndStoreOrdered(T *newValue)
Атомарная операция fetch-and-store.
Считывает текущее значение этого QAtomicPointer и присваивает ему newValue, возвращая исходное значение.
Эта функция использует семантику упорядочивания памяти ordered, которая гарантирует, что доступ к памяти до и после атомарной операции (в порядке программы) не может быть переупорядочен.
T *QAtomicPointer::fetchAndStoreRelaxed(T *newValue)
Атомарная операция fetch-and-store.
Считывает текущее значение этого QAtomicPointer и присваивает ему newValue, возвращая исходное значение.
Эта функция использует семантику упорядочивания памяти relaxed, оставляя компилятору и процессору свободу в переупорядочивании доступа к памяти.
T *QAtomicPointer::fetchAndStoreRelease(T *newValue)
Атомарная операция fetch-and-store.
Считывает текущее значение этого QAtomicPointer и присваивает ему newValue, возвращая исходное значение.
Эта функция использует семантику упорядочивания памяти release, которая гарантирует, что доступ к памяти перед атомарной операцией (в порядке программы) не может быть переупорядочен после атомарной операции.
[static] bool QAtomicPointer::isFetchAndAddNative()
Возвращает true true, если fetch-and-add реализована с использованием атомных инструкций процессора, false в противном случае.
[static] bool QAtomicPointer::isFetchAndAddWaitFree()
Возвращает true true, если атомарная операция fetch-and-add является свободной от ожидания, false в противном случае.
[static] bool QAtomicPointer::isFetchAndStoreNative()
Возвращает true true, если fetch-and-store реализована с использованием атомных инструкций процессора, false в противном случае.
[static] bool QAtomicPointer::isFetchAndStoreWaitFree()
Возвращает true если атомарная операция fetch-and-store ожидает без блокировок, иначе false.
[static] bool QAtomicPointer::isTestAndSetNative()
Возвращает true если test-and-set реализован с использованием атомарных инструкций процессора, иначе false.
[static] bool QAtomicPointer::isTestAndSetWaitFree()
Возвращает true если атомарная операция test-and-set ожидает без блокировок, иначе false.
T *QAtomicPointer::loadAcquire() const
Атомарно загружает значение этого QAtomicPointer с использованием семантики памяти «Acquire». Значение не изменяется, но нет гарантии, что оно останется неизменным.
См. также storeRelease() и loadRelaxed().
T *QAtomicPointer::loadRelaxed() const
Атомарно загружает значение этого QAtomicPointer с использованием расслабленной семантики памяти. Значение не изменяется, но нет гарантии, что оно останется неизменным.
Эта функция была добавлена в Qt 5.14.
См. также storeRelaxed() и loadAcquire().
void QAtomicPointer::storeRelaxed(T *newValue)
Атомарно сохраняет значение newValue в этот атомарный тип с использованием расслабленной семантики памяти.
Эта функция была добавлена в Qt 5.14.
См. также storeRelease() и loadRelaxed().
void QAtomicPointer::storeRelease(T *newValue)
Атомарно сохраняет значение newValue в этот атомарный тип с использованием семантики памяти «Release».
См. также storeRelaxed() и loadRelaxed().
bool QAtomicPointer::testAndSetAcquire(T *expectedValue, T *newValue)
Атомарная операция test-and-set.
Если текущее значение этого QAtomicPointer равно expectedValue, операция test-and-set присваивает newValue этому QAtomicPointer и возвращает true. Если значения не совпадают, функция ничего не делает и возвращает false.
Эта функция использует семантику памяти acquire, что гарантирует, что доступ к памяти, следующей за атомарной операцией (в порядке программы), не может быть переупорядочен до атомарной операции.
bool QAtomicPointer::testAndSetOrdered(T *expectedValue, T *newValue)
Атомарная операция test-and-set.
Если текущее значение этого QAtomicPointer равно expectedValue, операция test-and-set присваивает newValue этому QAtomicPointer и возвращает true. Если значения не совпадают, функция ничего не делает и возвращает false.
Эта функция использует семантику памяти ordered, гарантируя, что доступ к памяти до и после атомарной операции (в порядке программы) не может быть переупорядочен.
bool QAtomicPointer::testAndSetRelaxed(T *expectedValue, T *newValue)
Атомарная операция test-and-set.
Если текущее значение этого QAtomicPointer равно expectedValue, операция test-and-set присваивает newValue этому QAtomicPointer и возвращает true. Если значения не совпадают, функция ничего не делает и возвращает false.
Эта функция использует семантику памяти relaxed, позволяя компилятору и процессору свободно переупорядочивать обращения к памяти.
bool QAtomicPointer::testAndSetRelease(T *expectedValue, T *newValue)
Атомарная операция test-and-set.
Если текущее значение этого QAtomicPointer равно expectedValue, операция test-and-set присваивает newValue этому QAtomicPointer и возвращает true. Если значения не совпадают, функция ничего не делает и возвращает false.
Эта функция использует семантику памяти release, гарантируя, что доступ к памяти до атомарной операции (в порядке программы) не может быть переупорядочен после атомарной операции.
Документация макросов
Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
Этот макрос определён, если и только если ваш процессор поддерживает атомарную операцию fetch-and-add для указателей.
Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
Этот макрос определён, если аппаратное обеспечение не поддерживает атомарную операцию fetch-and-add для указателей.
Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
Этот макрос определён, если атомарная операция fetch-and-add для указателей поддерживается только определёнными поколениями процессоров. Используйте функцию QAtomicPointer::isFetchAndAddNative() для проверки поддержки вашим процессором.
Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE
Этот макрос определён вместе с Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE, чтобы указать, что атомарная операция fetch-and-add для указателей ожидает без блокировок.
Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
Этот макрос определён, если и только если ваш процессор поддерживает атомарную операцию fetch-and-store для указателей.
Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE
Этот макрос определён, если аппаратное обеспечение не поддерживает атомарную операцию fetch-and-store для указателей.
Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
Этот макрос определён, если атомарная операция fetch-and-store для указателей поддерживается только определёнными поколениями процессоров. Используйте функцию QAtomicPointer::isFetchAndStoreNative() для проверки поддержки вашим процессором.
Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
Этот макрос определён вместе с Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE, чтобы указать, что атомарная операция fetch-and-store для указателей ожидает без блокировок.
Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
Этот макрос определён, если и только если ваш процессор поддерживает атомарную операцию test-and-set для указателей.
Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
Этот макрос определён, если аппаратное обеспечение не поддерживает атомарную операцию test-and-set для указателей.
Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE
Этот макрос определён, если атомарная операция test-and-set для указателей поддерживается только определёнными поколениями процессоров. Используйте функцию QAtomicPointer::isTestAndSetNative() для проверки поддержки вашим процессором.
Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE
Этот макрос определён вместе с Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE, чтобы указать, что атомарная операция test-and-set для указателей ожидает без блокировок.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.15/qatomicpointer.html