std::atomic原子操作

1、原子操作介绍

在多线程编程中,经常使用互斥锁锁住一段代码块,实现线程同步。原子操作可以看成是对变量的互斥锁。比如程序中一个线程读取一个变量,另一个线程修改该变量的值,那么采用原子操作可以不用添加互斥锁即可实现线程同步。

2、原子操作实例

采用原子操作,定义了一个全局变量iCount。

#include 
#include 
#include 
#include 

std::atomic iCount(0);

void threadFunc1()
{
    for (size_t i = 0; i < 100; i++)
    {
        std::cout << "iCount = " << iCount++ << std::endl;
    }

    return;
}

void threadFunc2()
{
    for (size_t i = 0; i < 100; i++)
    {
        std::cout << "iCount = " << iCount-- << std::endl;
    }

    return;
}

int main(int argc, char **argv)
{
    std::vector vecThread;
    for (size_t i = 0; i < 100; i++)
    {
        vecThread.push_back(std::thread(threadFunc1));
    }

    for (size_t i = 0; i < 100; i++)
    {
        vecThread.push_back(std::thread(threadFunc2));
    }

    for (auto &th : vecThread)
    {
        th.join();
    }

    std::cout << "Finally iCount = " << iCount.load() << std::endl;
    return 0;
}

std::atomic原子操作_第1张图片

输出结果是0.

如果不采用原子操作:

#include 
#include 
#include 
#include 

int iCount = 0;

void threadFunc1()
{
    for (size_t i = 0; i < 100; i++)
    {
        std::cout << "iCount = " << iCount++ << std::endl;
    }

    return;
}

void threadFunc2()
{
    for (size_t i = 0; i < 100; i++)
    {
        std::cout << "iCount = " << iCount-- << std::endl;
    }

    return;
}

int main(int argc, char **argv)
{
    std::vector vecThread;
    for (size_t i = 0; i < 100; i++)
    {
        vecThread.push_back(std::thread(threadFunc1));
    }

    for (size_t i = 0; i < 100; i++)
    {
        vecThread.push_back(std::thread(threadFunc2));
    }

    for (auto &th : vecThread)
    {
        th.join();
    }

    std::cout << "Finally iCount = " << iCount << std::endl;
    return 0;
}

 std::atomic原子操作_第2张图片

输出结果是-5, 而且每次运行,结果都不一样。

 3、注意事项

原子操作的初始化不能写成如下形式

std::atomic iCount = 0;

会出现编译错误 error: use of deleted function

如果使用cmake编译,需要添加Threads库,本文采用的CMakeLists.txt文件如下

cmake_minimum_required(VERSION 2.8.0)

project(atomic_test)

find_package(Threads REQUIRED)

add_executable(test_with_atomic test_with_atomic.cpp)
target_link_libraries(test_with_atomic Threads::Threads)

add_executable(test_without_atomic test_without_atomic.cpp)
target_link_libraries(test_without_atomic Threads::Threads)

4、参考文献

1、c++11 std::atomic - 简书

2、CMake中使用pthread实践 - 知乎

你可能感兴趣的:(C++,c++)