如何在C ++中将原子变量用作互斥体?

问题描述

我有一个程序,其中有四个线程同时运行在一个“银行帐户”上的提款/存款操作

我应该将线程与原子同步(学校任务)。我目前使用的是compare_exchange,它可用于存款(加法),因为加法何时完成都无关紧要。

但是,提款存在问题,因为帐户无法转为负数。

示例。 假设帐户余额为300,线程1要提取200,检查其确定可以继续提取功能。 使用compare_exchange,期望值为300,新值为300-200。 Thread2也想同时从账户中提款200,两个线程都检查确定并输入提款,现在是哪个使它变得无关紧要 首先但第二个现在应该是预期的300到100,然后是100-200,这样我们就会得出帐户为负数的情况。

我进行了大量交易,但确实发生了 我目前有这段代码用于撤消操作

void withdraw(int amount)
{
    float old = m_iBalance.load();
    while(!m_iBalance.compare_exchange_weak(old,old - amount))
    {
        //
    }
    if (m_iBalance < 0 )
    {
        cout << m_iBalance << endl;
    }
    
}

如何使用原子作为互斥锁,一次只允许一个线程访问撤回功能

解决方法

这是您想要的吗?

class Account
{
public:
    Account(double balance)
        : m_balance(balance)
    {
    }


    void Deposit(double amount)
    {
        double old_amount,new_amount;
        do {
            old_amount = m_balance.load();
            new_amount = old_amount + amount;
        } while (!m_balance.compare_exchange_weak(old_amount,new_amount));
    }

    bool Withdraw(double amount)
    {
        double old_amount,new_amount;
        do {
            old_amount = m_balance.load();
            new_amount = old_amount - amount;
            if (new_amount < 0) return false;
        } while (!m_balance.compare_exchange_weak(old_amount,new_amount));

        return true;
    }

    double Amount() const { return m_balance.load(); }

protected:
    std::atomic<double> m_balance;
};

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...