Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何编写原子帐户转移函数_C++_Pthreads_Critical Section - Fatal编程技术网

C++ 如何编写原子帐户转移函数

C++ 如何编写原子帐户转移函数,c++,pthreads,critical-section,C++,Pthreads,Critical Section,假设我有两个银行账户A和B,我需要自动转账。 设置如下所示: ` ` 我的做法如下: ` ` 函数将资金从账户转移到账户,返回bool,仅当账户中剩余资金>=amount时转移。 这个函数是一个合适的方法吗?我想它不会导致死锁问题,但它不会使整个函数成为非原子函数吗?所以可能会有比赛条件?请帮帮我,非常感谢。您的代码在逻辑上被破坏了。无论from_帐户的余额如何,to_帐户都将无条件赢得帐户!我想成为您的帐户所有者: 在这种情况下,您必须获取两个帐户的两个锁,这可能会导致死锁问题 避免死锁的最简

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

`

我的做法如下: `

`

函数将资金从账户转移到账户,返回bool,仅当账户中剩余资金>=amount时转移。
这个函数是一个合适的方法吗?我想它不会导致死锁问题,但它不会使整个函数成为非原子函数吗?所以可能会有比赛条件?请帮帮我,非常感谢。

您的代码在逻辑上被破坏了。无论from_帐户的余额如何,to_帐户都将无条件赢得帐户!我想成为您的帐户所有者:

在这种情况下,您必须获取两个帐户的两个锁,这可能会导致死锁问题

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

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;
}

这个函数不是原子函数。还有比赛条件。还有死锁的情况。而且它也不是例外安全的。所以,不。这不是一个好的方法。请问一个具体的问题。此外,您考虑使用什么平台?@ USER?我只是好奇如何用基本的C锁来解决这个问题。什么是好的策略?设置一个全局锁定序列怎么样?
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;
}
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;
}