22.C++中的原子操作

C++中的原子操作


欢迎访问个人网络日志🌹🌹知行空间🌹🌹


C++的原子操作也是为了解决多线程编程中同步的问题,它保证在执行原子操作时不会被其他线程干扰。原子操作分为原子赋值和原子递增/递减操作。

原子赋值操作一般用于初始化一个共享资源,确保在多个线程同时访问时,不会出现多个线程同时修改同一个资源的情况。

原子递增/递减操作一般用于计数器,确保在多个线程同时访问时,不会出现多个线程同时修改同一个计数器的情况。

atomic_flag

std::atomic_flagC++中的一个原子布尔类型,用于实现原子锁操作。默认情况下,它是清除状态(false)。可以使用ATOMIC_FLAG_INIT宏进行初始化。std::atomic_flag类型的对象必须由宏ATOMIC_FLAG_INIT初始化,它把标志初始化为置零状态:std::atomic_flag f=ATOMIC_FLAG_INITstd::atomic_flag对象永远以置零状态开始,别无他选。

std::atomic_flag对象只能执行3种操作:销毁、置零、读取原有的值并设置标志成立。这分别对应于析构函数成员函数clear()成员函数test_and_set()

clear()是存储操作,因此无法采用std::memory_order_acquirestd::memory_order_acq_rel内存次序,test_and_set()是“读-改-写”操作,因此能采用任何内存次序,对于上面两种操作,默认的内存序都是最严格的std::memory_order_seq_cst

使用atomic_flag的一个示例:

#include <iostream>
#include <atomic>
#include <thread>

std::atomic_flag flag = ATOMIC_FLAG_INIT;

void taskFunc(int tid)
{
   
    while(flag.test_and_set(std::memory_order_acquire)) {
    } // 相当于上锁
    std::cout << "Thread " << tid << " acquired the lock" << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::cout << "Thread " << tid << " released the lock" << std::endl;
    flag.clear(std::memory_order_release); // 相当于解锁
}

int main(int argc, char **argv)
{
   
    std::thread t1(taskFunc, 1);
    std::thread t2(taskFunc, 2);
    t1.join();
    t2.join();
    return 0;
}

通过上面的例子,很容易发现可以借助atomic_flag实现自旋锁:

class SpinLockMutex
{
   
    std::atomic_flag flag_{
   ATOMIC_FLAG_INIT};
public:
    void lock()
    {
   
        while (flag_.test_and_set(std::memory_order_acquire))
        {
   
            /* spin */
        }
    }

    void unlock(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值