Класс QAtomicPointer
Класс QAtomicPointer — это шаблонный класс, который предоставляет независимые от платформы атомарные операции над указателями. Подробнее...
| Заголовок: | #include <QAtomicPointer> |
| qmake: | QT += core |
| С тех пор: | Qt 4.4 |
| Наследует: | QBasicAtomicPointer |
Этот класс был представлен в 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 * | load() const |
| T * | loadAcquire() const |
| void | store(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(). Смотрите выше объяснение различных семантик упорядочения памяти.
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 если атомарная операция fetch-and-add ожидает без блокировок, в противном случае — false.
[static] bool QAtomicPointer::isFetchAndStoreNative()
Возвращает 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::load() const
Атомарно загружает значение этого QAtomicPointer с использованием расслабленного порядка памяти. Значение не изменяется, но нет гарантии, что оно останется неизменным.
См. также store() и loadAcquire().
T *QAtomicPointer::loadAcquire() const
Атомарно загружает значение этого QAtomicPointer с использованием порядка памяти «Acquire». Значение не изменяется, но нет гарантии, что оно останется неизменным.
void QAtomicPointer::store(T *newValue)
Атомарно сохраняет значение newValue в этот атомарный тип с использованием расслабленного порядка памяти.
См. также storeRelease() и load().
void QAtomicPointer::storeRelease(T *newValue)
Атомарно сохраняет значение newValue в этот атомарный тип с использованием порядка памяти «Release».
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, которая гарантирует, что доступ к памяти до атомарной операции (в порядке программы) не может быть переупорядочен после атомарной операции.
Документация макросов
QAtomicPointer::Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
Этот макрос определен тогда и только тогда, когда ваш процессор поддерживает атомарную операцию fetch-and-add для указателей.
QAtomicPointer::Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
Этот макрос определен, когда оборудование не поддерживает атомарную операцию fetch-and-add для указателей.
QAtomicPointer::Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
Этот макрос определен, когда атомарная операция fetch-and-add для указателей поддерживается только определенными поколениями процессоров. Используйте функцию QAtomicPointer::isFetchAndAddNative(), чтобы проверить, какую поддержку обеспечивает ваш процессор.
QAtomicPointer::Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE
Этот макрос определен вместе с Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE, чтобы указать, что атомарная операция fetch-and-add для указателей выполняется без ожидания блокировок.
QAtomicPointer::Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
Этот макрос определен тогда и только тогда, когда ваш процессор поддерживает атомарную операцию fetch-and-store для указателей.
QAtomicPointer::Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE
Этот макрос определен, когда оборудование не поддерживает атомарную операцию fetch-and-store для указателей.
QAtomicPointer::Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
Этот макрос определен, когда атомарная операция fetch-and-store для указателей поддерживается только определенными поколениями процессоров. Используйте функцию QAtomicPointer::isFetchAndStoreNative(), чтобы проверить, какую поддержку обеспечивает ваш процессор.
QAtomicPointer::Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
Этот макрос определен вместе с Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE, чтобы указать, что атомарная операция fetch-and-store для указателей выполняется без ожидания блокировок.
QAtomicPointer::Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
Этот макрос определен тогда и только тогда, когда ваш процессор поддерживает атомарную операцию test-and-set для указателей.
QAtomicPointer::Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
Этот макрос определен, когда оборудование не поддерживает атомарную операцию test-and-set для указателей.
QAtomicPointer::Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE
Этот макрос определен, когда атомарная операция test-and-set для указателей поддерживается только определенными поколениями процессоров. Используйте функцию QAtomicPointer::isTestAndSetNative(), чтобы проверить, какую поддержку обеспечивает ваш процессор.
QAtomicPointer::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.13/qatomicpointer.html