- 浏览: 45068 次
- 性别:
- 来自: 上海
最新评论
-
HappyBlueCat:
关于你的JAVA问题,提下我的看法:关于这方面,JAVA和C、 ...
对于JAVA中passed by reference & passed by value -
ZangXT:
java的引用其实就是指针,不过在语言层面对它可以进行的操作进 ...
对于JAVA中passed by reference & passed by value
最近学习多线程编程,并且以Win32作为实验平台,看了点东西感觉应该稍微有所实践。
因此拿了哲学家进餐问题作了实验品,以来检验最近学习CriticalSection和Mutex的成果
哲学家进餐问题我做了稍微的简化,没有什么左边一个筷子和又边一个筷子。全部简化为总共6根筷子和六个傻冒哲学家,然后大家一起米西米西。
任务目标
1.模拟死锁的发生
2.用CriticalSection解除死锁
3.用Mutex解除死锁
1. 模拟死锁的发生
结果发现6位傻冒很快就进入相互等待死锁的状态。
然后使用CriticalSection来解除死锁
结果发现再也没有死锁过,然后使用Mutex来解除死锁
下一篇将会使用Event来完成上述相同的任务。
今天顺便参考了一下其他已成的代码,发现对于互斥的情况下,使用CriticalSection比较多,当然他的缺点就是不能够在进程间形成互斥,但是他的速度是Mutex的100倍,毕竟别人不是核心对象。
因此拿了哲学家进餐问题作了实验品,以来检验最近学习CriticalSection和Mutex的成果
哲学家进餐问题我做了稍微的简化,没有什么左边一个筷子和又边一个筷子。全部简化为总共6根筷子和六个傻冒哲学家,然后大家一起米西米西。
任务目标
1.模拟死锁的发生
2.用CriticalSection解除死锁
3.用Mutex解除死锁
1. 模拟死锁的发生
// Philosopher problem #include <windows.h> #include <stdio.h> #include <time.h> const int MAX_TIME = 5; bool chopsticks[6] = {false, false, false, false, false, false}; class Philosopher { private: char* name; HANDLE philosopherOperation; DWORD threadId; int firstChopstickIndex; int secondChopstickIndex; public: Philosopher(const char* name): firstChopstickIndex(-1), secondChopstickIndex(-1) { SetName(name); philosopherOperation = CreateThread(NULL, 0, Philosopher::BeginOperation, this, 0, &threadId); } void SetName(const char* name) { this->name = const_cast<char*>(name); } static DWORD WINAPI BeginOperation(LPVOID p) { Philosopher* pointer = reinterpret_cast<Philosopher*>(p); while(true) { pointer->Thinking(); pointer->Waiting(); pointer->Eating(); } return 0; } void Thinking() { int time = rand() % 5 + 1; printf("%s think for %d seconds\n", this->name, time); Sleep(time * 1000); } void Eating() { int time = rand()% 5 + 1; printf("%s eat for %d seconds\n", this->name, time); Sleep(time * 1000); chopsticks[firstChopstickIndex] = false; chopsticks[secondChopstickIndex] = false; firstChopstickIndex = -1; secondChopstickIndex = -1; } void Waiting() { while(true) { if (firstChopstickIndex == -1) { for (int i = 0; i < 6; ++i) { if (!chopsticks[i]) { chopsticks[i] = true; firstChopstickIndex = i; break; } } } Sleep(0.5*1000); //Make it easy to reproduce thread dead lock if (secondChopstickIndex == -1) { for (int i = 0; i < 6; ++i) { if (!chopsticks[i]) { chopsticks[i] = true; secondChopstickIndex = i; break; } } } if (firstChopstickIndex != -1 && secondChopstickIndex != -1) { return; } else { printf("%s is waiting\n", this->name); } } } }; void Initialize() { srand((unsigned int)time(NULL)); // set random seed } void BeginEmulate() { Philosopher p1("XYT"); Philosopher p2("WS"); Philosopher p3("WL"); Philosopher p4("WYF"); Philosopher p5("LLB"); Philosopher p6("JXL"); Sleep(3600 * 1000); } int main() { Initialize(); BeginEmulate(); return 0; }
结果发现6位傻冒很快就进入相互等待死锁的状态。
然后使用CriticalSection来解除死锁
// Philosopher problem #include <windows.h> #include <stdio.h> #include <time.h> const int MAX_TIME = 5; bool chopsticks[6] = {false, false, false, false, false, false}; CRITICAL_SECTION criticalSection; class Philosopher { private: char* name; HANDLE philosopherOperation; DWORD threadId; int firstChopstickIndex; int secondChopstickIndex; public: Philosopher(const char* name): firstChopstickIndex(-1), secondChopstickIndex(-1) { SetName(name); philosopherOperation = CreateThread(NULL, 0, Philosopher::BeginOperation, this, 0, &threadId); } void SetName(const char* name) { this->name = const_cast<char*>(name); } static DWORD WINAPI BeginOperation(LPVOID p) { Philosopher* pointer = reinterpret_cast<Philosopher*>(p); while(true) { pointer->Thinking(); pointer->Waiting(); pointer->Eating(); } return 0; } void Thinking() { int time = rand() % 5 + 1; printf("%s think for %d seconds\n", this->name, time); Sleep(time * 1000); } void Eating() { int time = rand()% 5 + 1; printf("%s eat for %d seconds\n", this->name, time); Sleep(time * 1000); chopsticks[firstChopstickIndex] = false; chopsticks[secondChopstickIndex] = false; firstChopstickIndex = -1; secondChopstickIndex = -1; } void Waiting() { while(true) { // add critical EnterCriticalSection(&criticalSection); if (firstChopstickIndex == -1) { for (int i = 0; i < 6; ++i) { if (!chopsticks[i]) { chopsticks[i] = true; firstChopstickIndex = i; break; } } } Sleep(0.5*1000); //Make it easy to reproduce thread dead lock if (secondChopstickIndex == -1) { for (int i = 0; i < 6; ++i) { if (!chopsticks[i]) { chopsticks[i] = true; secondChopstickIndex = i; break; } } } LeaveCriticalSection(&criticalSection); if (firstChopstickIndex != -1 && secondChopstickIndex != -1) { return; } else { printf("%s is waiting\n", this->name); //Sleep(1000); } } } }; void Initialize() { InitializeCriticalSection(&criticalSection); srand((unsigned int)time(NULL)); // set random seed } void BeginEmulate() { Philosopher p1("XYT"); Philosopher p2("WS"); Philosopher p3("WL"); Philosopher p4("WYF"); Philosopher p5("LLB"); Philosopher p6("JXL"); Sleep(3600 * 1000); } int main() { Initialize(); BeginEmulate(); DeleteCriticalSection(&criticalSection); return 0; }
结果发现再也没有死锁过,然后使用Mutex来解除死锁
// Philosopher problem #include <windows.h> #include <stdio.h> #include <time.h> const int MAX_TIME = 5; bool chopsticks[6] = {false, false, false, false, false, false}; HANDLE mutex; class Philosopher { private: char* name; HANDLE philosopherOperation; DWORD threadId; int firstChopstickIndex; int secondChopstickIndex; public: Philosopher(const char* name): firstChopstickIndex(-1), secondChopstickIndex(-1) { SetName(name); philosopherOperation = CreateThread(NULL, 0, Philosopher::BeginOperation, this, 0, &threadId); } void SetName(const char* name) { this->name = const_cast<char*>(name); } static DWORD WINAPI BeginOperation(LPVOID p) { Philosopher* pointer = reinterpret_cast<Philosopher*>(p); while(true) { pointer->Thinking(); pointer->Waiting(); pointer->Eating(); } return 0; } void Thinking() { int time = rand() % 5 + 1; printf("%s think for %d seconds\n", this->name, time); Sleep(time * 1000); } void Eating() { int time = rand()% 5 + 1; printf("%s eat for %d seconds\n", this->name, time); Sleep(time * 1000); chopsticks[firstChopstickIndex] = false; chopsticks[secondChopstickIndex] = false; firstChopstickIndex = -1; secondChopstickIndex = -1; } void Waiting() { while(true) { // add critical WaitForSingleObject(mutex, INFINITE); if (firstChopstickIndex == -1) { for (int i = 0; i < 6; ++i) { if (!chopsticks[i]) { chopsticks[i] = true; firstChopstickIndex = i; break; } } } Sleep(0.5*1000); //Make it easy to reproduce thread dead lock if (secondChopstickIndex == -1) { for (int i = 0; i < 6; ++i) { if (!chopsticks[i]) { chopsticks[i] = true; secondChopstickIndex = i; break; } } } ReleaseMutex(mutex); if (firstChopstickIndex != -1 && secondChopstickIndex != -1) { return; } else { printf("%s is waiting\n", this->name); //Sleep(1000); } } } }; void Initialize() { mutex = CreateMutex(NULL, false, NULL); srand((unsigned int)time(NULL)); // set random seed } void BeginEmulate() { Philosopher p1("XYT"); Philosopher p2("WS"); Philosopher p3("WL"); Philosopher p4("WYF"); Philosopher p5("LLB"); Philosopher p6("JXL"); Sleep(3600 * 1000); } int main() { Initialize(); BeginEmulate(); CloseHandle(mutex); return 0; }
下一篇将会使用Event来完成上述相同的任务。
今天顺便参考了一下其他已成的代码,发现对于互斥的情况下,使用CriticalSection比较多,当然他的缺点就是不能够在进程间形成互斥,但是他的速度是Mutex的100倍,毕竟别人不是核心对象。
发表评论
-
Win32多线程学习之二(实现生产者与消费者模型)
2011-10-13 21:51 1323#include <Windows.h> # ... -
深入理解C++中多态的实现
2010-12-22 22:29 1529对于C++中多态性是面向 ... -
[转]追MM与Java的23种设计模式
2010-09-19 21:21 990追MM与Java的23种设计模 ... -
关于C++引用类型变量
2010-09-05 12:01 2396随着设计模式的学习和 ... -
【转】拷贝构造函数和赋值函数的必要性和意义
2010-03-10 23:01 2828引用链接: http://hi.baidu ... -
深入理解计算机系统验证代码1
2010-01-23 21:35 1435/* 此程序测试了深入理解计算机系统中的 1. ... -
《代码揭秘》阅读有感一
2009-10-17 22:36 15872009-10-17 《代码揭秘》阅读有感一 今天,《代码揭 ... -
C++编译、链接过程
2009-07-30 23:10 6193C++程序从编译到链接然后再到调用的整个过程如下。 只是个人最 ... -
链接器都干了些什么
2009-07-27 00:13 1259目前项目在不停的增长 ... -
程序中的堆和栈
2009-04-26 01:20 1009[转载]栈和堆的区别 信 ...
相关推荐
ztsc_109339.apk
永磁同步电机的高频正弦电压注入的速度观测,Simulink,PMSM,高频正弦。
智慧燃气发展研究报告
如何通过智能卡读写器SDK接入鸿蒙操作系统?通过智能卡读写器提供的SDK范例可以将智能卡读写器接入在运行鸿蒙操作系统的智能终端设备上。
谭浩强编写的《C程序设计(第五版)》PPT、书中源码、习题答案以及习题库
人力资源+大数据+薪酬报告+涨薪调薪,在学习、工作生活中,越来越多的事务都会使用到报告,通常情况下,报告的内容含量大、篇幅较长。那么什么样的薪酬报告才是有效的呢?以下是小编精心整理的调薪申请报告,欢迎大家分享。相信老板看到这样的报告,一定会考虑涨薪的哦。
分布式驱动汽车稳定性控制。 采用分层式直接横摆力矩控制,上层滑模控制,下层基于轮胎滑移率最优分配。 滑模控制跟踪横摆角速度和质心侧偏角误差。 七自由度整车模型输出实际质心侧偏角和横摆角速度,二自由度模型输出理想质心侧偏角和横摆角速度。 附m文件,有参考文献和说明文档
注意:此文档为最终版本,方便大家记录,但更新主要还是在博客更新
汇川.H5U框架程序,汇川TIT700系列触摸屏框架程序 1.汇川H5U-A8系列cpu 自制封装多个FB功能块程序,轴控制功能块,气缸动作报警功能块,XY矩阵功能块,等等。 只需写动作步序,其他全部调用FB 和HMI可以无实物仿真 仿真HMI地址127.0.0.1 A1349.H5U原框架
学生作业-作业打卡盖章。该项目为html前端项目,依据学生作业提交情况,通过点击名字进行打卡盖章。涉及html、js、css,其中js中涉及监听函数;窗口中的列表数据来源于data.jso,可自行修改
Spring面试专题.pdf
2025年蓝色简约时尚婚礼邀请函模板
深层过滤纸板是一种由纤维素材料制成的平板或薄片,具有过滤液体或气体的能力。它通常由纤维素纤维(如木浆)经过湿法造纸工艺制成,形成一张薄而均匀的纸板。深层过滤纸板设计用于过滤任何类型的液体,包括葡萄酒、油、啤酒和果汁等,广泛应用于食品饮料、制药、化工等领域。 随着酿酒行业和饮料行业的不断壮大,对深层过滤纸板的需求也在增加。深层过滤纸板常用于过滤液体中的杂质和固体颗粒,确保产品的质量和纯度。因此,这些行业的发展推动了过滤纸板的需求。为了满足酿酒行业和饮料行业对过滤效果、速度和成本的不断追求,深层过滤纸板制造商进行了技术创新和改进。他们不断改良过滤纸板的材料、结构和制造工艺,以提高其过滤效率和性能,同时降低生产成本。环保意识的提升推动了过滤纸板行业朝着绿色、可持续发展的方向发展。包括可降解材料的应用,再生纤维的使用以及生产过程的绿色化都是行业发展的趋势。 目前在全球范围内,工业化的发展仍处于高速阶段,企业在生产过程中要求更高的过滤处理标准,从而促进了深层过滤纸板行业的发展。随着生物技术产业的发展,越来越多的实验室需要使用过滤纸板进行细胞和菌群的分离,同时也需要更高精度的滤料来处理许多疾病的检
该项目包含完整的前后端代码、数据库脚本和相关工具,简单部署即可运行。功能完善、界面美观、操作简单,具有很高的实际应用价值,非常适合作为Java毕业设计或Java课程设计使用。 所有项目均经过严格调试,确保可运行!下载后即可快速部署和使用。 1 适用场景: 毕业设计 期末大作业 课程设计 2 项目特点: 代码完整:详细代码注释,适合新手学习和使用 功能强大:涵盖常见的核心功能,满足大部分课程设计需求 部署简单:有基础的人,只需按照教程操作,轻松完成本地或服务器部署 高质量代码:经过严格测试,确保无错误,稳定运行 3 技术栈和工具 前端:HTML + Vue.js 后端框架:Spring Boot 开发环境:IntelliJ IDEA 数据库:MySQL(建议使用 5.7 版本,更稳定) 数据库可视化工具:Navicat 部署环境:Tomcat(推荐 7.x 或 8.x 版本),Maven
easy-interceptor修改请求头和响应头.zip
代码复现;冷热电气多门互补的微能源网鲁棒优化调度MATLAB复现 随着能源结构调整,集成风/光等可再生能源输入、冷热电气等多种能源互补输出的微能源网得到了逐步发展,如何协调调度微能源网内冷热电气源网荷成为当前研究热点。 建立了冷热电气多能互补的微能源网在孤岛/并网模式下的协调调度模型,并利用供热/供冷系统的热惯性和热/冷负荷的柔性,发挥供热/供冷系统的“储能”功能,以电转气(P2G)装置实现电—气网络双向互通。 模型采用鲁棒线性优化理论将随机优化模型进行确定性转化,取得经济性和鲁棒性的适当折中。 算例仿真验证了温度负荷储能特性对微能源网灵活调度的优化作用和鲁棒性指标对优化结果的协 调作用。 关键词:微能源网;多能互补;温度负荷;储能特性;鲁棒优化
三电平T型变器双闭环PI控制-调制实现在60度坐标系 变器 减少了普通SVPWM的矢量计算时间,在60度坐标系完成高效计算,控制效果很好。 可以发参考资料
该项目包含完整的前后端代码、数据库脚本和相关工具,简单部署即可运行。功能完善、界面美观、操作简单,具有很高的实际应用价值,非常适合作为Java毕业设计或Java课程设计使用。 所有项目均经过严格调试,确保可运行!下载后即可快速部署和使用。 1 适用场景: 毕业设计 期末大作业 课程设计 2 项目特点: 代码完整:详细代码注释,适合新手学习和使用 功能强大:涵盖常见的核心功能,满足大部分课程设计需求 部署简单:有基础的人,只需按照教程操作,轻松完成本地或服务器部署 高质量代码:经过严格测试,确保无错误,稳定运行 3 技术栈和工具 前端:HTML + Vue.js 后端框架:Spring Boot 开发环境:IntelliJ IDEA 数据库:MySQL(建议使用 5.7 版本,更稳定) 数据库可视化工具:Navicat 部署环境:Tomcat(推荐 7.x 或 8.x 版本),Maven
箱线图(Box Plot)是一种用于展示数据分布的图形工具,能够有效地显示数据的集中趋势和离散程度。以下是箱线图的主要特点和组成部分: 主要特点 数据分布:箱线图可以清晰地展示数据的中位数、四分位数和潜在的异常值。 多组比较:可以将多组数据在同一张图中进行可视化,便于比较不同组之间的差异。 易于理解:由于其结构清晰,读取和理解相对简单。 使用场景 数据分析:用于探讨数据的分布和变化,识别异常值。 统计总结:在数据报告和研究中,用于直观表达数据特征。
ChromeDriver 是一个用于自动化 Chrome 浏览器的工具,它是由 Selenium WebDriver 提供支持的。在测试领域,尤其是Web应用程序的自动化测试中,ChromeDriver扮演着至关重要的角色。标题"chromedriver version 118.0.5993.70"表明这是 ChromeDriver 的一个特定版本,版本号为118.0.5993.70,通常这样的更新会带来性能优化、新功能以及对Chrome浏览器新版本的支持。 描述中的“chromedriver测试版本”意味着这可能是一个用于测试目的的构建,可能包含了最新的改进或者尚未广泛发布的特性。开发者和测试工程师会使用这样的测试版本来确保他们的自动化测试脚本能够兼容即将推出的 ChromeDriver 正式版本。 标签“测试 chromedriver”进一步强调了该软件在测试环境中的应用,特别是与 Chrome 浏览器的自动化测试相关的场景。ChromeDriver 允许测试人员通过编写 Selen。内容来源于网络分享,如有侵权请联系我删除。另外如果没有积分的同学需要下载,请私信我。