实现银行转账的死锁

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

运行截图如下

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

  1. 面试官:手写一个必然死锁的例子?一顿操作猛如虎。。

    来源:blog.csdn.net/xiewenfeng520/article/details/107230996 前言 只对死锁代码感兴趣的可以直接跳到第三小节 必然死锁示例,如果对死锁还不太了解的, ...

  2. Java多线程学习四十:如何写一个必然死锁的例子

    死锁是什么?有什么危害? 什么是死锁 发生在并发中 首先你要知道,死锁一定发生在并发场景中.我们为了保证线程安全,有时会给程序使用各种能保证并发安全的工具,尤其是锁,但是如果在使用过程中处理不得当,就 ...

  3. mysql死锁 简单例子_写一个Mysql死锁的例子

    创建表 CREATE TABLE `test1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(10) NOT NULL, PRIMAR ...

  4. 一个多线程死锁案例,如何避免及解决死锁问题?

    多线程死锁在java程序员笔试的时候时有遇见,死锁概念在之前的文章有介绍,大家应该也都明白它的概念,不清楚的去翻看历史文章吧. 下面是一个多线程死锁的例子 public class lock{priv ...

  5. 一个多线程死锁案例,如何避免及解决死锁问题

    转载自 一个多线程死锁案例,如何避免及解决死锁问题 多线程死锁在java程序员笔试的时候时有遇见,死锁概念在之前的文章有介绍,大家应该也都明白它的概念,不清楚的去翻看历史文章吧. 下面是一个多线程死锁 ...

  6. 如何彻底解决烦人的 MySQL 分库分表问题?写一个更好的数据库!

    作者 | 黄东旭 责编 | 郭   芮 我还清楚记得,五年前的这个时候,当时还在豌豆荚,午后与刘奇和崔秋的闲聊关于未来数据库的想象,就像一粒种子一样,到了今天看起来也竟枝繁叶茂郁郁葱葱,有点感慨.按照 ...

  7. html 原生弹出框,html、css和js原生写一个模态弹出框,顺便解决父元素半透明子元素不透明效果...

    模态框: html部分: 弹出框 hhhhh 取消 确认 css部分: #box{ width: 80px; height: 40px; background: #fd7430; border:non ...

  8. 怎样才能把一个代码变成软件成品?一个初学者的困惑,我们写的代码都只能是解决一些数学问题而已。怎么把它变成一个软件。

    小弟疑惑... 怎样才能把一个代码变成软件成品?一个初学者的困惑,我们写的代码都只能是解决一些数学问题而已.怎么把它变成一个软件. 大神月... 对于您这个问题,当初也是我的好奇之处啊!其实你学好一门 ...

  9. 用scala写一个基本五级流水线CPU(二)解决数据冒险

    用scala写一个基本五级流水线CPU(二)解决数据冒险 ctime:2020-06-27 10:17:34 +0900|1593220654 标签(空格分隔): 技术 硬件 所谓数据冒险,即后面的指 ...

  10. 用python写一个小程序,解决买水果的问题?

    问题: 商店总共有三种水果,香蕉/苹果/葡萄,单价分别为3.5/5.0/3.0元/500克. 写一个小程序实现: 1.输出一个菜单:打印每种水果的价格: 2.寻问客户欲购买水果? 3.客户想购买的克数 ...

最新文章

  1. Java集合TreeSet
  2. 4)线性表[顺序表和链表]
  3. 使用ucontext组件实现的coroutine代码分析
  4. Linux运维之道之ENGINEER1.3(配置SMB共享,配置NFS共享)
  5. MySQL统计两部分查询结果记录数量比值
  6. XP计算机里改单核,XP中多核处理器只显示单核
  7. 常见音视频编码格式一览
  8. 〔转〕Word域的应用和详解2_等式和公式域
  9. 【机器学习入门到精通系列】元胞自动机和代码举例(这一篇就够了!)
  10. HTML5数据可视化第四弹:交互式地铁线路图
  11. ODI 11g安装记录
  12. css动画效果-animation
  13. 苹果:付费才能用 iOS 开发者预览版,网友吐槽:找 Bug,还得先交 99 美元?
  14. 递四方(4PX)一面
  15. java生成word排版_java生成word(文字和图片)
  16. 校园网自动登录,断线重连
  17. Halcon 第七章『图像的几何变换』◆第1节:图像的仿射变换(位置变换、形状变换)及应用
  18. photoshop时钟制作过程
  19. Python入门之基础知识(三)
  20. Zoom WebTeam面经

热门文章

  1. 【SSH】Spring框架学习
  2. centos php ioncube_CentOS 7安装ionCube Loader为php解密组件的方法
  3. Astah Professional三维图,网络上轻松上传图表
  4. dell刷sn_像API一样地通过Dell设备SN号自动获取准确的设备型号
  5. 天池大数据竞赛——UI特征统计
  6. Js坐标转换器-百度地图坐标转腾讯地图坐标
  7. Web渗透测试工程师:入门知识
  8. ADByby 自定义过滤语法简表
  9. Oracle 11g企业版下载
  10. mc全国计算机一级考试,全国计算机等级考试一级模拟试题04