<MFC笔记>多线程编程之线程的特性
2014-06-10 21:14
274 查看
一,线程的特性
1,随机性,系统在执行多线程程序时只保证线程是交替执行的,至于哪个线程先执行哪个线程后执行,则无法获得保证,需要书写专门的代码才可以保证执行的顺序。
2,多线程无法预测其行为,可能获得不同的结果。当然想要达到预期的效果需要xxx(暂时没有搞清楚)
3,task switches可能在任何时刻任何地点发生
4,线程对小的变化有高度的敏感
二,不可预测性和随机性
1,创建一个win32 console application工程,本工程创建了两个支线程,两个支线程执行模拟火车售票的程序!
输入代码如下:
2,结果(以下均为未更改代码的前提下多次运行的结果)
图未接完,只展示前面的部分数据!
三,解决上诉现象
(利用互斥对象实现线程同步)
1,在上诉代码的基础上添加代码如下:红色为新添加的代码!
2,运行结果(多次运行的如果都是如此)
3,运行结果分析
(1)CreateMutex(NULL,FALSE,NULL)各参数的意义(顺序解释):默认安全性,创建该互斥对象的线程不获得这个互斥对象,创建一个匿名的互斥对象!一定要记住:谁拥有互斥对象,谁就必须释放!如果设置为TRUE则,必须在主程序释放互斥对象。
(2)WaitForSingleObject(hMutex,INFINITE):互斥对象,无限等待线程来请求互斥对象的所有权。当运行到这一句时线程1和线程2就会一直等待,除非所等待的互斥对象hMetux处于有信号状态(即没有被“别人”拿走了钥匙,或者说互斥对象没有被申请!)
(3)程序的执行过程:当第一个线程运行时,进入while循环,申请“钥匙”(此时钥匙没有被拿走),所以线程1得到了互斥对象(操作系统随后将互斥对象的线程id改为线程1的id),线程1便继续执行下去,调用sleep,暂停一小会,于是系统会选择线程2开始执行,该线程执行过程也一样!!!但是因为互斥对象已经被线程1所拥有,处于无信号状态所以线程2一直处于等待状态!线程1暂停结束,开始执行任务,最后释放所有权!线程2申请得到互斥对象,开始执行任务,然后释放......................
1,随机性,系统在执行多线程程序时只保证线程是交替执行的,至于哪个线程先执行哪个线程后执行,则无法获得保证,需要书写专门的代码才可以保证执行的顺序。
2,多线程无法预测其行为,可能获得不同的结果。当然想要达到预期的效果需要xxx(暂时没有搞清楚)
3,task switches可能在任何时刻任何地点发生
4,线程对小的变化有高度的敏感
二,不可预测性和随机性
1,创建一个win32 console application工程,本工程创建了两个支线程,两个支线程执行模拟火车售票的程序!
输入代码如下:
输入代码如下: #include "windows.h" #include "iostream.h" DWORD WINAPI FunProc1(LPVOID lpParameter); DWORD WINAPI FunProc2(LPVOID lpParameter); static int ticket=100; void main() { HANDLE hThread1; HANDLE hThread2; hThread1=CreateThread(NULL,0,FunProc1,NULL,0,NULL); hThread2=CreateThread(NULL,0,FunProc2,NULL,0,NULL); CloseHandle(hThread1); CloseHandle(hThread2); Sleep(4000); } DWORD WINAPI FunProc1(LPVOID lpParameter) { while(TRUE) { if(ticket>0) { cout<<"ticket 1:"<<ticket--<<endl; } else break; } return 0; } DWORD WINAPI FunProc2(LPVOID lpParameter) { while(TRUE) { if(ticket>0) { cout<<"ticket 2:"<<ticket--<<endl; } else break; } return 0; }
2,结果(以下均为未更改代码的前提下多次运行的结果)
图未接完,只展示前面的部分数据!
三,解决上诉现象
(利用互斥对象实现线程同步)
1,在上诉代码的基础上添加代码如下:红色为新添加的代码!
#include "windows.h" #include "iostream.h" DWORD WINAPI FunProc1(LPVOID lpParameter); DWORD WINAPI FunProc2(LPVOID lpParameter); static int ticket=100; HANDLE hMutex; //保存互斥对象 void main() { HANDLE hThread1; HANDLE hThread2; hMutex=CreateMutex(NULL,FALSE,NULL); //创建互斥对象,互斥对象可比喻成钥匙</span> hThread1=CreateThread(NULL,0,FunProc1,NULL,0,NULL); hThread2=CreateThread(NULL,0,FunProc2,NULL,0,NULL); CloseHandle(hThread1); CloseHandle(hThread2); Sleep(4000); } DWORD WINAPI FunProc1(LPVOID lpParameter) { while(TRUE) {WaitForSingleObject(hMutex,INFINITE); //申请“钥匙”(即互斥对象)的所有权,一直等待 if(ticket>0) { Sleep(1); //让线程1暂停1毫秒</span> cout<<"ticket 1:"<<ticket--<<endl; } else break; ReleaseMutex(hMutex); //执行完后,释放所有权 } return 0; } DWORD WINAPI FunProc2(LPVOID lpParameter) { while(TRUE) { WaitForSingleObject(hMutex,INFINITE);</span> if(ticket>0) {Sleep(1); cout<<"ticket 2:"<<ticket--<<endl; } else break; ReleaseMutex(hMutex); } return 0; }
2,运行结果(多次运行的如果都是如此)
3,运行结果分析
(1)CreateMutex(NULL,FALSE,NULL)各参数的意义(顺序解释):默认安全性,创建该互斥对象的线程不获得这个互斥对象,创建一个匿名的互斥对象!一定要记住:谁拥有互斥对象,谁就必须释放!如果设置为TRUE则,必须在主程序释放互斥对象。
(2)WaitForSingleObject(hMutex,INFINITE):互斥对象,无限等待线程来请求互斥对象的所有权。当运行到这一句时线程1和线程2就会一直等待,除非所等待的互斥对象hMetux处于有信号状态(即没有被“别人”拿走了钥匙,或者说互斥对象没有被申请!)
(3)程序的执行过程:当第一个线程运行时,进入while循环,申请“钥匙”(此时钥匙没有被拿走),所以线程1得到了互斥对象(操作系统随后将互斥对象的线程id改为线程1的id),线程1便继续执行下去,调用sleep,暂停一小会,于是系统会选择线程2开始执行,该线程执行过程也一样!!!但是因为互斥对象已经被线程1所拥有,处于无信号状态所以线程2一直处于等待状态!线程1暂停结束,开始执行任务,最后释放所有权!线程2申请得到互斥对象,开始执行任务,然后释放......................
相关文章推荐
- Java6学习笔记57——多线程编程——线程的互斥(version 0.2)
- mfc多线程编程之三——线程间通讯
- <MFC笔记>多线程编程简单实例
- <MFC笔记>BMP位图文件的格式及其操作
- <MFC笔记>MFC消息映射机制
- Java多线程编程总结笔记——一多线程基础知识
- 多线程编程学习3——使用MFC工作者线程
- <MFC多线程>多线程经典面试问题
- <MFC多线程> 读者写者问题
- Java多线程编程总结笔记——五线程状态的转换
- [原]Java多线程编程学习笔记之一:线程中断(含代码)
- Java笔记3 多线程<1>线程概述、多线程的创建、多线程的安全问题、静态同步函数的锁、死锁
- <MFC多线程> 某培训机构的多线程练习题
- Java6学习笔记55——多线程编程——线程的创建方法1
- Java多线程编程总结笔记——六线程的同步与锁
- MFC多线程编程之三——线程间通讯
- No MFC 编程05 - 进程 > 线程 > 消息队列,三者的包含关系
- MFC多线程编程之四——线程的同步
- <<ASP.NET MVC4 Web编程>>笔记
- <MFC多线程> 一道迅雷多线程编程题