C++ 如何实现原子性

1.操作系统如何实现原子性

在单处理器,单核,运行多线程的情况下,我们不使用线程同步工具,

我们会出现,线程之间会互相抢夺,临界区的资源,造成数据不符合我们预期的结果,

后面再说解决办法,那么我们怎么帮助实现原子性

1 屏蔽中断,不让线程之间切换,让它完成再切换

2 底层硬件自旋锁,也是不让切换的思路

在多处理器,多核,运行多线程的情况下,除了上面两点,我们该如何保持原子性呢?

让我们先了解一下 多核 cpu 之间是如何通信的:

如图,通过CPU总线 进行数据交换

问题 1

因为我们每个核心都在执行任务,当我们执行任务时,都在对同一个数据进行修改

那么到底用 哪一个数据呢?

问题 2

当 我们 使用缓存时,数据在缓存 与 磁盘上不一致时,CPU 该如何保持呢?

一致性协议,就是解决这种问题,

所以 当我们 想使用 具有 原子性 的变量时,使用 修改(modified)独占(exclusive) 的数据

2.在c++中如何实现线程同步

1.使用 条件变量和锁

写一个例子:

三个线程轮流 输出 1 2 3 到 100

cpp 复制代码
std::condition_variable cond;
std::mutex mtu;
int nums = 1;
void fun1()
{
    while (nums <= 100)
    {
        {
            std::unique_lock<std::mutex> lock(mtu);
            if (nums % 3 == 1)
            {
                cout << "nums 1:" << nums << endl;
                nums++;
                cond.notify_all();
            }
            else
            {
                cond.wait(lock);
            }
        }
    }
    cond.notify_all();
}
void fun2()
{
    while (nums <= 100)
    {
        {
            std::unique_lock<std::mutex> lock(mtu);
            if (nums % 3 == 2)
            {
                cout << "nums 2:" << nums << endl;
                nums++;
                cond.notify_all();
            }
            else
            {
                cond.wait(lock);
            }
        }
    }
    cond.notify_all();
}
void fun3()
{
    while (nums <= 100)
    {
        {
            std::unique_lock<std::mutex> lock(mtu);
            if (nums % 3 == 0)
            {
                cout << "nums 3:" << nums << endl;
                nums++;
                cond.notify_all();
            }
            else
            {
                cond.wait(lock);
            }
        }
    }
    cond.notify_all();
}
int main()
{
    std::thread t1(fun1);
    std::thread t2(fun2);
    std::thread t3(fun3);

    t1.join();
    t2.join();
    t3.join();
    cout << "打印完毕" << endl;
    return 0;
}

2.使用atomic

cpp 复制代码
std::atomic<int> nums(1);

void print_nums(int remainder)
{
    while (nums <= 100)
    {
        int current_nums;
        do
        {
            current_nums = nums.load();
        } while (current_nums % 3 != remainder && !nums.compare_exchange_weak(current_nums, current_nums + 1));

        if (current_nums <= 100)
        {
            std::cout << "nums " << remainder + 1 << ":" << current_nums << std::endl;
        }
    }
}

int main()
{
    std::thread t1(print_nums, 1);
    std::thread t2(print_nums, 2);
    std::thread t3(print_nums, 0);

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

    std::cout << "打印完毕" << std::endl;

    return 0;
}
相关推荐
Ryan_Gosling5 分钟前
C++-构造函数-接口
开发语言·c++
ceffans15 分钟前
PDF文档中文本解析
c++·windows·pdf
SummerGao.21 分钟前
Windows 快速搭建C++开发环境,安装C++、CMake、QT、Visual Studio、Setup Factory
c++·windows·qt·cmake·visual studio·setup factory
仟濹25 分钟前
【二分搜索 C/C++】洛谷 P1873 EKO / 砍树
c语言·c++·算法
YH_DevJourney1 小时前
Linux-C/C++《C/8、系统信息与系统资源》
linux·c语言·c++
Igallta_8136222 小时前
【小游戏】C++控制台版本俄罗斯轮盘赌
c语言·开发语言·c++·windows·游戏·游戏程序
在雨中6123 小时前
【找工作】C++和算法复习(自用)
c++·算法
攻城狮7号3 小时前
【第二节】C++设计模式(创建型模式)-抽象工厂模式
c++·设计模式·抽象工厂模式
天线枫枫4 小时前
QT- HTTP + JSON(还需完善)
c++·qt·http
天若有情6735 小时前
【数据结构】C++实现链表数据结构
数据结构·c++·链表