银行情况出现僵局问题

发布于 2024-11-06 07:32:56 字数 471 浏览 0 评论 0原文

我有一个问题,我无法解决这个问题

void Transfer(Account a, Account b, decimal amount) 
{
       lock (a) {
             lock (b) {
                         if (a.Balance < amount)
                         throw new InsufficientFundsExc();
                         a.Balance -= amount;
                         b.Balance += amount;
                         }
                   }
}

,问题是“这是银行帐户之间的转账。”lock(...)”结构用于对抗竞争条件。这是什么问题?您提出什么解决方案?可以你帮我吗?

I have a problem, i cannot resolve this problem

void Transfer(Account a, Account b, decimal amount) 
{
       lock (a) {
             lock (b) {
                         if (a.Balance < amount)
                         throw new InsufficientFundsExc();
                         a.Balance -= amount;
                         b.Balance += amount;
                         }
                   }
}

and question is " this is a transfer between bank accounts. "lock(...)" structure is used against race condition. What is this problem? and what solution do you propose? CAN YOU HELP ME?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

星星的轨迹 2024-11-13 07:32:56

如果您在从 B 到 A 的转账的同时进行从 A 到 B 的转账,则可能会出现死锁,因为您没有锁定订单。

  • 线程 1 锁定 A
  • 线程 2 锁定 B
  • 线程 1 等待 B
  • 线程 2 等待 A
  • 死亡

但是为什么这段代码首先是多线程的呢?

您需要始终按照相同的顺序取锁。例如,为每个锁提供一个整数 ID,并始终首先锁定较低的 ID。

if you have a transfer from A to B at the same time as a transfer from B to A it can deadlock because you have no lock order.

  • Thread 1 locks A
  • Thread 2 locks B
  • Thread 1 waits on B
  • Thread 2 waits on A
  • dead

But why the hell is this code multithreaded in the first place?

You need to take your locks always in the same order. For example by giving each lock an integer Id and always locking the lower ID first.

天暗了我发光 2024-11-13 07:32:56

如果您可以对帐户进行排序(通过 ID 号或其他方式),您始终可以先锁定 ID 较低的帐户。这将确保没有线程尝试在另一个线程先锁定 a 然后 b 的同时先锁定 a 然后 b >,因为它们都会首先锁定a

If you can order the accounts (by ID number or something), you can always lock the one with the lower ID first. This will ensure that no thread tries to lock a then b at the same time as another thread locking a then b, as they will both lock a first.

待"谢繁草 2024-11-13 07:32:56

死锁

Transfer(a,b,10.0) 时发生 ;和传输(b,a,10.0);同时被调用
第一次调用将锁定
那么第二个可以在第一个锁定 a 之前锁定 b
都无法继续 ->僵局

deadlock

when Transfer(a,b,10.0); and Transfer(b,a,10.0); are called simultaneously
the first call will lock a
then the second can lock b before the first can lock a
and neither can continue -> deadlock

顾北清歌寒 2024-11-13 07:32:56

正如 CodeInChaos 所暗示的那样,您的问题是潜在的死锁。如果您不明白什么是死锁,那么我建议您阅读维基百科上的哲学家就餐问题

本文实际解释了该问题,并提出了一些解决方案,包括使用锁定顺序

编辑:
为了进一步将您的问题与本文联系起来,银行帐户是分叉(即只能独占使用的共享资源,因此需要锁定),访问代码的线程是哲学家(即不时需要使用的实体)可锁定资源)。

As CodeInChaos suggests, your problem is a potential deadlock. If you don't understand what a deadlock is then I recommend reading the dining philosophers problem on Wikipedia.

The article explains the problem in real terms and suggests some solutions including using a locking order.

Edit:
To further relate your problem to the article, the bank accounts are forks (i.e. shared resources that can only be used exclusively therefore need to be locked) and the threads accessing the code are the philosophers (i.e. entities that from time to time require the use of lockable resources).

傲性难收 2024-11-13 07:32:56

@RatchetFreak 对于为什么会发生这种情况的回答一针见血。我认为您遇到的主要问题是锁是一个非常低级别的构造,这使得很难理智地考虑线程场景。

我建议(如果可能的话)使用一组稍高级别的构造来让自己的生活更轻松。 Daniel Chamber 在他的库中提供了一套很好的轻量级实用程序。

@RatchetFreak hit the nail on the head with his response regarding why this has occured. I think the main problem that you are having it that a lock is a very low level construct which makes it difficult to think about threading scenario's sanely.

I would recommend (if possible) to use a set of slightly higher level constructs to make life easier on yourself. Daniel Chamber's has a good light weight set of utilities for this in his library.

滥情哥ㄟ 2024-11-13 07:32:56

想象一下,两个非常固执的女士和她们的丈夫一起去度假屋。第二天早上他们醒来,发现那些人已经走了。剩下的唯一衣服:一条裙子和一件衬衫(似乎其中一个男人喜欢穿女装 - 可以解释很多)。女士们意识到需要去买东西——食物、衣服、新丈夫。她们都想“好吧,我穿上衣服就走”,一个穿上裙子,另一个穿上衬衫。他们看到了发生的事情,但每个人都太固执,无法改变他们的计划(而且太害羞,不敢半裸出去)。他们的固执就像一台愚蠢的计算机遵循着“当时看起来不错”的程序。他们不能/不会自动修改他们在遇到“运行时错误”时所采取的看似明智的方法,因此他们都注定要饿死。这是一个死锁:等待你无法获得的资源,因为有人在等待你自己占用的资源。

如果有更多的远见和计划,他们本可以找到一种策略来确保他们中的一个人逃脱。例如:

  • 基于所寻找的对象的顺序:
    • 例如,只有当你已经拿到裙子时,你才能拿衬衫(至少有锁,保证争夺它的两条线之一可以拿到它,而不会把它撕成两半),或者
  • 根据意愿订购-成为业主:
    • 如果两人同时出去,谁生日早谁先去,如果生日相同则谁高,依此类推,OR
  • 都再次脱光并在短暂但随机的间隔后尝试

等等。

Imagine two very stubborn ladies went to a holiday house with their husbands. They woke the next morning and found the men gone. The only clothes left: a skirt and a shirt (seems one of the men liked wearing women's clothing - could explain a lot). The ladies realise the need to go get stuff - food, clothes, new husbands. They both think "well, I'll put the clothes on and go", and one puts on the skirt while the other dons the shirt. They see what's happened but each is too stubborn to change their plan (and way too shy to go out half naked). Their stubbornness is akin to a dumb computer following a program that "looked good at the time". They can't/won't automatically revise the seemingly sensible approach they had above on hitting a "run-time error", so they are both doomed to starve to death. That's a dead lock: waiting for resources you can't get because someone's waiting for what you're hogging yourself.

With a bit more foresight and planning, they could have found a strategy that would make sure one of them got out. For example:

  • order based on the objects being sought:
    • e.g. only when you've already got the skirt can you take the shirt (at least with locks, one of two threads contesting it is guanteed to get it without ripping it in two), OR
  • order based on the would-be owners:
    • if both want to go out at the same time, whoever's birthday is earlier can go first, or if the same then whoever's taller etc, OR
  • both strip again and try after a short but random interval

etc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文