zoukankan      html  css  js  c++  java
  • Qt QAtomicPointer

    QAtomicPointer类是一个模板类,它对指针提供与平台无关的原子操作

    template <typename T> class QAtomicPointer

    头文件:

    #include <QAtomicPointer>

    cmake:

    1 find_package(Qt6 COMPONENTS Core REQUIRED)
    2 target_link_libraries(mytarget PRIVATE Qt6::Core)

    qmake:

    QT += core

    详细说明

    有关整数的原子操作,请参阅QAtomicInteger类。

    原子操作是一种不间断完成的复杂操作。QAtomicPointer类为指针提供了原子的测试和设置、获取和存储以及获取和添加。

    原子API

    内存排序

    QAtomicPointer提供了原子测试和设置、获取和存储以及获取和添加函数的几种实现。每个实现都定义了一个内存排序语义,该语义描述了处理器如何执行围绕原子指令的内存访问。由于许多现代架构允许乱序执行和内存排序,因此使用正确的语义是必要的,以确保您的应用程序在所有处理器上正常运行。

    • Relaxed:非指定的内存排序,使编译器和处理器可以自由地对内存访问进行重新排序。
    • Acquire:原子操作之后的内存访问(按程序顺序)不能在原子操作之前重新排序。
    • Release:原子操作之前的内存访问(按程序顺序)不能在原子操作之后重新排序。
    • Ordered:相同的获取和发布语义组合

    测试并设置

    如果QAtomicPointer的当前值是期望值,则测试设置函数将新值分配给QAtomicPointer并返回true。如果值不相同,则这些函数不执行任何操作并返回false。此操作等于以下代码:

    1 if (currentValue == expectedValue) {
    2     currentValue = newValue;
    3     return true;
    4 }
    5 return false;

    有4个测试设置函数:testAndSetRelaxed(), testAndSetAcquire(), testAndSetRelease(), testAndSetOrdered()。有关不同的内存排序语义的说明,请参见上文。

    提取并存储

    原子获取和存储功能读取QAtomicPointer的当前值,然后分配一个新值,并返回原始值。此操作等于以下代码:

    1 T *originalValue = currentValue;
    2 currentValue = newValue;
    3 return originalValue;

    有4个访存函数:fetchAndStoreRelaxed(), fetchAndStoreAcquire(), fetchAndStoreRelease(), fetchAndStoreOrdered()。有关不同的内存排序语义的说明,请参见上文。

    提取并添加

    原子获取和添加函数读取QAtomicPointer的当前值,然后将给定值添加到当前值,并返回原始值。此操作等于以下代码:

    1 T *originalValue = currentValue;
    2 currentValue += valueToAdd;
    3 return originalValue;

    有4个获取和添加函数:fetchAndAddRelaxed(), fetchAndAddAcquire(), fetchAndAddRelease(), fetchAndAddOrdered().。有关不同的内存排序语义的说明,请参见上文。

    原子API的功能测试

    提供可在所有处理器上工作的独立于平台的原子API具有挑战性。QAtomicPointer提供的API可以保证在所有处理器上以原子方式工作。但是,由于不是所有处理器都实现对QAtomicPointer提供的每个操作的支持,因此有必要公开有关处理器的信息。

    您可以在编译时使用各种宏检查硬件上支持哪些特性。这些将告诉您,您的硬件是否总是、有时或不支持特定的操作。宏的形式是Q_ATOMIC_POINTER_OPERATION_IS_HOW_NATIVE。操作是TEST_AND_SET, FETCH_AND_STORE,或FETCH_AND_ADD之一,而HOW是ALWAYS, SOMETIMES, or NOT之一。每次操作都只有一个已定义的宏。例如,如果定义了Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE,那么Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_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()函数检查硬件支持什么。可以使用isstestandsetwaitfree()、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::QAtomicPointer(const QAtomicPointer &other)

    构造other的副本。

    QAtomicPointer::QAtomicPointer(T *value = nullptr)

    构造一个具有给定值的QAtomicPointer 。

    operator=

    QAtomicPointer &QAtomicPointer::operator=(const QAtomicPointer &other)

    将other赋值给这个QAtomicPointer,并返回对这个QAtomicPointer的引用。

    fetchAndAddAcquire

    *QAtomicPointer::fetchAndAddAcquire(qptrdiff valueToAdd)

    原子获取和添加。

    读取该QAtomicPointer的当前值,然后将valueToAdd添加到当前值,返回原始值。

    这个函数使用了获取内存排序语义,这确保了原子操作之后的内存访问(按程序顺序)不会在原子操作之前重新排序。

    fetchAndAddOrdered

    *QAtomicPointer::fetchAndAddOrdered(qptrdiff valueToAdd)

    原子获取和添加。

    读取该QAtomicPointer的当前值,然后将valueToAdd添加到当前值,返回原始值。

    这个函数使用有序的内存排序语义,它确保原子操作之前和之后的内存访问(按程序顺序)不会被重新排序。

  • 相关阅读:
    Delphi Code Editor 之 几个特性(转)
    如何访问局域网的Access数据库?
    Delphi Live Bindings 初探
    重装Delphi10.2的IDE必要设置
    TClientDataSet数据源设置
    js删除数组里的某个数据
    初识localstorage用法
    Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.
    css实现文本溢出用...显示
    原生js和jquery
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/14918366.html
Copyright © 2011-2022 走看看