防止模拟银行数据库中的死锁 [英] Preventing deadlock in a mock banking database

查看:67
本文介绍了防止模拟银行数据库中的死锁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个模拟银行数据库问题,涉及死锁.我已经找到了答案,但是我很好奇这是否是一个好的解决方案.提出的问题如下:

This is a mock bank database problem involving deadlock. I already have what I think is the answer, but I'm curious if this is a good solution. The question posed is the following:

如何防止以下代码中的死锁?:

How do you prevent deadlock in the following code?:

void transaction(Account from, Account to, double amount)
{
    Semaphore lock1, lock2;
    lock1 = getLock(from);
    lock2 = getLock(to);

    wait(lock1);
       wait(lock2);

          withdraw(from, amount);
          deposit(to, amount);

       signal(lock2);
    signal(lock1);
 }

这种方式陷入僵局的方法是通过两个线程(或进程?)使用相反的帐户同时调用transaction()方法,即:

The way this can become deadlocked is via two threads (or processes?) calling the transaction() method at the same time with opposing accounts, i.e.:

交易(储蓄,检查,1);在线程1和

transaction(savings, checking, 1); in thread 1 and

交易(检查,节省,2);在线程2中.

transaction(checking, savings, 2); in thread 2.

从我的拙劣理解出发,我认为发生了什么事情以及为什么它陷入僵局是因为两个线程都试图(相互之间)试图获得一个锁,所以没有遵守锁的排序.

From my poor understanding, I think what is going on and why it is getting deadlocked is because the lock ordering is not obeyed since both threads are trying to get a lock (from each other?).

我的快速而肮脏的解决方案是将锁从函数transaction()移到调用时的样子:

My quick and dirty solution would be to move the locks outside of the function transaction() to where it would look like this when called:

 //somewhere in main
    Semaphore lock1, lock2;
    lock1 = getLock(from);
    lock2 = getLock(to);

    wait(lock1);
       wait(lock2);

       transaction(checking, savings, 2);

       signal(lock2);
    signal(lock1);
    //.....

交易如下:

void transaction(Account from, Account to, double amount)
{
   withdraw(from, amount);
   deposit(to, amount);
}

那样,由于事务在技术上是至关重要的部分,因此它们永远不能同时执行.如果这是一个Java程序,您是否还可以通过在函数声明中的void之后放置同步单词来使用监视器?那行得通吗?这似乎是一种更明智的方法.

That way they can never be executed at the same time, since transaction is technically the critical section. If this were a java program, could you also use monitors by putting the word synchronized after void in the function declaration? Would that work? That seems like a smarter way to do it.

我可能也一点都不理解,所以请随时向我学习,尤其是在我的解释不正确的情况下.谢谢.

I also may not be understanding this at all, so feel free to school me, especially if my explanations are not accurate. Thanks.

推荐答案

我认为这是怎么回事以及为什么会死锁是因为两个线程都试图获取锁,所以没有遵守锁的顺序

I think what is going on and why it is getting deadlocked is because the lock ordering is not obeyed since both threads are trying to get a lock

这里的问题是,正如您提到的那样,有一个线程像do:

The problem here is as you mention that one thread like do:

wait(fromLock);
   wait(toLock);

而另一个可能会做:

wait(toLock);
   wait(fromLock);

这可能导致死锁.

您需要做的是确保它们始终以相同的顺序锁定.您可以通过某种方式使用帐户的ID来确定锁的顺序:

What you need to do is insure that they always lock in the same order. You could use the id of the account somehow to figure out the order of the locks:

if (from.id < to.id) {
   wait(fromLock)
     wait(toLock)
       transaction(checking, savings, 2);
     signal(toLock);
   signal(fromLock);
} else {
   wait(toLock)
     wait(FromLock)
       transaction(checking, savings, 2);
     signal(FromLock);
   signal(toLock);
}

我相信这将解决所有僵局.您可能还想检查 from to 是否为同一实体.

I believe that will resolve any deadlocks. You might also want to put a check for the from and to being the same entity.

这篇关于防止模拟银行数据库中的死锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆