如何在 C++ 中将原子变量用作互斥锁?
How to use atomic variable as a mutex in C++?
我有一个程序,其中有 4 个线程 运行 在“银行账户”上同时进行取款/存款操作
我应该将线程与原子同步(学校任务)。我目前正在使用 compare_exchange 并且它适用于存款(加法),因为加法何时完成并不重要。
但是提款有问题,因为账户不能为负值。
例子。
比方说账户余额是 300,thread1 想要提取 200,检查它是否正常并继续执行提取功能。
使用 compare_exchange ,期望值是 300,新的是 300-200。
Thread2 也想同时从账户中取出 200,两个线程都检查 ok 并进入 withdraw,现在不管是哪个线程了
第一个但第二个现在已经期望从 300 到 100,然后是 100 - 200,我们达到账户为负的情况。
我 运行 一个大的 t运行saction 号并且它确实发生了
我目前有这段提取操作的代码
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;
}
}
如何使用 atomic 作为互斥锁,一次只允许一个线程访问 withdraw 函数?
这是你想要的吗?
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;
};
我有一个程序,其中有 4 个线程 运行 在“银行账户”上同时进行取款/存款操作
我应该将线程与原子同步(学校任务)。我目前正在使用 compare_exchange 并且它适用于存款(加法),因为加法何时完成并不重要。
但是提款有问题,因为账户不能为负值。
例子。 比方说账户余额是 300,thread1 想要提取 200,检查它是否正常并继续执行提取功能。 使用 compare_exchange ,期望值是 300,新的是 300-200。 Thread2 也想同时从账户中取出 200,两个线程都检查 ok 并进入 withdraw,现在不管是哪个线程了 第一个但第二个现在已经期望从 300 到 100,然后是 100 - 200,我们达到账户为负的情况。
我 运行 一个大的 t运行saction 号并且它确实发生了 我目前有这段提取操作的代码
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;
}
}
如何使用 atomic 作为互斥锁,一次只允许一个线程访问 withdraw 函数?
这是你想要的吗?
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;
};