340-写一个银行转账死锁问题并且解决

实现银行转账的死锁

#include <mutex>
#include <iostream>
#include <thread>
#include <condition_variable>
using namespace std;
mutex mxA;
mutex mxB;
int countA = 1000;
int countB = 1000;

void thread_func1(int money) //A---> B转账money元
{
    //实现A给B账户转账 那么先对A上锁
    unique_lock<mutex> lcA(mxA);
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));//睡眠,保证线程1获得A账户的锁
    cout << "线程1获得了A账户的锁" << endl;
    if (countA > money)//满足转账要求
    {
        cout << "线程1请求B账户的锁子" << endl;
        unique_lock<mutex> lcB(mxB);//申请转账对象B的锁
        countA -= money;
        countB += money;
        cout << "转账成功A------>B:" << money << endl;
    }
    else//不满足转账要求
    {
        cout << "A账户余额不足" << endl;
    }
}

void thread_func2(int money) //B----->A转账money元
{
    //实现B给A账户转账 那么先对B上锁
    unique_lock<mutex> lcB(mxB);
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));//睡眠,保证线程2获得B账户的锁
    cout << "线程2获得了B账户的锁" << endl;
    if (countB > money)//满足转账要求
    {
        cout << "线程2请求A账户的锁子" << endl;
        unique_lock<mutex> lcA(mxA);//申请转账对象A的锁
        countB -= money;
        countA += money;
        cout << "转账成功B----->A:" << money << endl;
    }
    else//不满足转账要求
    {
        cout << "B账户余额不足" << endl;
    }
}


int main()
{
    thread s1(thread_func1, 100);
    thread s2(thread_func2, 200);
    s1.join();
    s2.join();
 
    return 0;
}

运行截图如下
在这里插入图片描述

解决银行死锁问题

分析死锁产生的四个条件

1.互斥

2.占有且等待。

3.不可抢占

4.循环等待

只要打破一个条件,即可解决上诉问题

方法:打破占有且等待 即只有持有所有资源的线程才可以直接进行操作。

#include <mutex>
#include <iostream>
#include <thread>
#include <condition_variable>
#include <set>
#include <unordered_set>
using namespace std;
mutex mx;
condition_variable cv;

class Count//账户类
{
public:
    Count(int m) : money(m) {}
    ~Count() = default;
    bool operator<(const Count& src)const { return money < src.money; }
    int getMoney() { return money; }
    void setMoney(int m) { money = m; }
private:
    int money;//现有的资产
};

class Account//管理类
{
public:
    ~Account() = default;
    static Account* getInstance()//初始化构建
    {
        static Account a;
        return &a;
    }
    void apply(Count& A, Count& B)//添加函数
    {
        unique_lock<mutex> lc(mx);//申请加锁
        while (s.count(A) > 0 || s.count(B) > 0)
        {
            cv.wait(lc); //阻塞等待,挂起
        }
        s.insert(A);//插入A资源
        s.insert(B);//插入B资源
    }
    void free(Count&A, Count& B)//释放函数
    {
        unique_lock<mutex> lc(mx);//申请加锁
        s.erase(A);//删除A资源
        s.erase(B);//删除B资源
        cv.notify_all();//唤醒所有线程
    }
private:
    Account() = default;
    Account(const Account& src) = delete;
    //删除缺省的拷贝构造函数
    Account& operator=(const Account& src) = delete;
    //删除缺省的=函数
    set<Count> s;//每一组值都是唯一的!!!

};

void thread_func1(Count& A, Count& B, int money) //A--->B转账money元
{
    Account* acc = Account::getInstance();//初始化
    acc->apply(A, B);//把A,B资源传入,调用

    if (A.getMoney() >= money)//满足转账要求
    {
        A.setMoney(A.getMoney() - money);//转账
        B.setMoney(B.getMoney() + money);//进账
        cout << "successful:" << endl;//打印“成功”
        cout << money << endl;//打印转账的金额数
    }
    else//不满足转账要求
    {
        cout << "余额不足" << endl;
    }
    acc->free(A, B);//释放资源
}

int main()
{
    Count A(1000);//创建A账户并初始化其账户值为1000元
    Count B(2000);//创建B账户并初始化其账户值为2000元
    thread s1(thread_func1, ref(A), ref(B), 300); 
    //A----->B 300  A给B转300元
    thread s2(thread_func1, ref(B), ref(A), 100); 
    //B----->A 100  B给A转100元
    s1.join();
    s2.join();
    cout << "A现在的账户上的值为:" << A.getMoney() << endl;
    cout << "B现在的账户上的值为:" << B.getMoney() << endl;

    return 0;
}

运行截图如下
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林林林ZEYU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值