C11线程管理:原子变量&单调函数

Posted 渔舟唱晚

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C11线程管理:原子变量&单调函数相关的知识,希望对你有一定的参考价值。

1、原子变量

  C++11提供了原子类型std::atomic<T>,可以使用任意类型作为模板参数,使用原子变量就不需要使用互斥量来保护该变量,用起来更加简洁。

  举个例子,如果要做一个计数器,使用mutex时和使用原子变量依次如下:

//使用mutex
 struct  Counter
{
    int value;
    std::mutex mutex;

    void increment()
    {
        std::lock_guard<std::mutex> lock(mutex);
        ++value;
    }

    void decrement()
    {
        std::lock_guard<std::mutex> lock(mutex);
        --value;
    }

    int get()
    {
        return value;
    }
};

int main()
{


    return 0;
}

//使用原子变量
#include <atomic>

struct  Counter
{
    std::atomic<int> value;

    void increment()
    {
        ++value;
    }

    void decrement()
    {
        --value;
    }

    int get()
    {
        return value;
    }
};

2、call_once/once_flag

  单调函数就是在多线程环境中,保证某个函数只被调用一次,比如要初始化某个对象,而这个对象只能被初始化一次,就可以使用std::call_once来保证函数在多线程环境中只被调用一次。使用std::call_once时,需要一个once_flag作为call_once的入参。

作为call_once的入参。
#include <thread>    
#include <iostream>   
#include <mutex>             

std::once_flag flag;

void do_once()
{
    std::call_once(flag, [](){ std::cout << "Called once." << std::endl; });
}

int main()
{
    std::thread t1(do_once);
    std::thread t2(do_once);
    std::thread t3(do_once);

    t1.join();
    t2.join();
    t3.join();

    return 0;
}
//输出:
Called once.

 

以上是关于C11线程管理:原子变量&单调函数的主要内容,如果未能解决你的问题,请参考以下文章

C11线程管理:线程创建

C11线程管理:异步操作

以只读模式对结构进行线程锁定(C11 stdatomic)

C11线程管理:互斥锁

C11新特性右值引用&&

JUC并发编程 共享模型之内存 -- Java 内存模型 & 原子性 & 可见性(可见性问题及解决 & 可见性 VS 原子性 & volatile(易变关键字))(代码