【问题标题】:how to write an atomic account transfer function如何编写一个原子账户转账函数
【发布时间】:2015-01-10 00:29:43
【问题描述】:

假设我有两个银行账户 A 和 B,我需要自动转账。 设置如下: `

struct account{
    int64 amount;
    pthread_mutex_lock m;
}

`

这是我的方法: `

bool Transfer(int from_account, int to_account, int64 amount) 
{
    pthread_lock(&account[from_account].m);
    bool ret = false;
    if(accounts[from_account].balance>=amount)
    {
        accounts[from_account].balance-=amount;
        ret = true;
    }
    pthread_unlock(&account[from_account].m);
    pthread_lock(&account[to_account].m);
    accounts[to_account].balance+=amount;
    pthread_unlock(&account[to_account].m);
    return ret;
}

`

from_account 到to_account 的转账函数,返回bool,只在账户余额时转账>=ammount。 这个功能是一个好的方法吗?我想它不会导致死锁问题,但它不会使整个函数成为非原子的吗?那么可能存在竞争条件?请帮助我,非常感谢。

【问题讨论】:

  • 这个函数不是原子的。并且有竞争条件。并且存在死锁情况。这不是例外安全的。所以不行。这不是一个好的方法。
  • 请提出具体问题。还有,什么平台?
  • @user3799934 您是否考虑过使用c++ standards thread and synchronisation support,而不是直接使用pthread
  • 感谢您的评论。我只是好奇如何仅使用基本的 C 锁来解决这个问题。什么是好的策略?全局设置一个锁定序列怎么样?

标签: c++ pthreads critical-section


【解决方案1】:

您的代码在逻辑上是错误的。不管from_account的余额如何,to_account都会无条件赢account! (我想成为 to_account 所有者:)

在这种情况下,您必须同时获得两个帐户的两个锁,这会导致潜在的死锁问题。

避免死锁的最简单方法是强制执行锁获取的顺序,例如,较小的索引帐户在前。

bool Transfer(int from_account, int to_account, int64 amount) 
{
  // acquire locks (in pre-defined order)
  if (from_account < to_account)
  {
    pthread_lock(&accounts[from_account].m);
    pthread_lock(&accounts[to_account].m);
  } else {
    pthread_lock(&accounts[to_account].m);
    pthread_lock(&accounts[from_account].m);
  }
  // transfer amount
  bool ret = false;
  if (accounts[from_account].balance >= amount)
  {
    accounts[from_account].balance -= amount;
    accounts[to_account].balance += amount;
    ret = true;
  }
  // release both locks
  pthread_unlock(&accounts[from_account].m);
  pthread_unlock(&accounts[to_account].m);
  return ret;
}

【讨论】:

    猜你喜欢
    • 2010-09-13
    • 2014-12-09
    • 2018-08-06
    • 2017-11-08
    • 2020-05-22
    • 2016-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多