- 浏览: 43742 次
- 性别:
- 来自: 上海
最新评论
-
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 1262#include <Windows.h> # ... -
深入理解C++中多态的实现
2010-12-22 22:29 1490对于C++中多态性是面向 ... -
[转]追MM与Java的23种设计模式
2010-09-19 21:21 908追MM与Java的23种设计模 ... -
关于C++引用类型变量
2010-09-05 12:01 2344随着设计模式的学习和 ... -
【转】拷贝构造函数和赋值函数的必要性和意义
2010-03-10 23:01 2769引用链接: http://hi.baidu ... -
深入理解计算机系统验证代码1
2010-01-23 21:35 1382/* 此程序测试了深入理解计算机系统中的 1. ... -
《代码揭秘》阅读有感一
2009-10-17 22:36 15482009-10-17 《代码揭秘》阅读有感一 今天,《代码揭 ... -
C++编译、链接过程
2009-07-30 23:10 6087C++程序从编译到链接然后再到调用的整个过程如下。 只是个人最 ... -
链接器都干了些什么
2009-07-27 00:13 1176目前项目在不停的增长 ... -
程序中的堆和栈
2009-04-26 01:20 962[转载]栈和堆的区别 信 ...
相关推荐
C#多线程学习(一) 多线程的相关概念 什么是进程? 什么是线程? 什么是多线程? 多线程的好处 多线程的不利方面 线程操作的关键对象和语句 任何程序在执行时,至少有一个主线程。 Thread类有几个至关重要的方法 C#...
C#多线程学习(一) 多线程的相关概念 1 什么是进程? 1 什么是线程? 1 什么是多线程? 1 多线程的好处 1 多线程的不利方面 1 线程操作的关键对象和语句 2 任何程序在执行时,至少有一个主线程。 2 Thread类有几个至...
C# 使用Mutex和AutoResetEvent类处理多线程同步与互斥,调试并完善了网上文档的代码。经测试能很好地实现要求,但还有一些地方不是特别明白,都写在注释中了,请高手给予指点。
C#多线程学习(一) 多线程的相关概念 1 什么是进程? 1 什么是线程? 1 什么是多线程? 1 多线程的好处 1 多线程的不利方面 1 线程操作的关键对象和语句 2 任何程序在执行时,至少有一个主线程。 2 Thread类...
操作系统课的一个小作业,使用C#处理多线程的同步与互斥,使用Mutex类和AutoResetEvent类。作为一个小白,参考了其他代码写出来,某些地方还有些不完全明白,都写在注释里了,求高手指点。
linux和win32下通用的互斥锁Mutex封装,统一接口,可直接使用
用C语言撰写的多线程win32程序,运用了mutex,semaphore和event来同步多个线程
使用Mutex对象实现多线程同步,打印输出结果,对比非同步情况下的输出结果,对比明显,更容易理解Mutex对象实际意义。
利用mutex object编写的多线程运用程序, 可以直接运行,可以手动改变线程优先级, 很直观。
这个例子利用多线程使用不同的...而且MFC还把线程分成用户界面线程和工作者线程,实质上用户界面线程跟工作者线程的差别是,用户界面线程要继承的基类已经实现了消息循环,MFC帮你做了很多的消息处理和界面控制的工作。
1.Qt下,多线程使用互斥锁安全访问同一全局变量;2.源码中定义了ThreadA和ThreadB,定义变量后,依次调用函数start()来启动重写的run()函数
多线程:C#线程同步lock,Monitor,Mutex,同步事件和等待句柄[整理].pdf
mutex在线程中的使用 简单操作 全局变量 在vs2008 c++
Linux线程同步之互斥量(mutex).pdf
操作系统课程实验,用win32实现生产者消费者问题
• 异步和多线程有什么关联 WinForm多线程编程篇 • 我的多线程WinForm程序老是抛出InvalidOperationException ,怎么解决? • Invoke,BeginInvoke干什么用的,内部是怎么实现的 • 每个线程都有消息队列吗? ...
LinuxC线程同步Mutex实例,让你一目了然
C#中使用Monitor类、Lock和Mutex类来同步多线程的执行.pdf
使用互斥对象(Mutex)实现线程同步。MFC工程