windows多线程(sunxin vc++ 笔记2)
来源:互联网 发布:手游美工价格 编辑:程序博客网 时间:2024/05/21 21:46
多线程
例1 多线程的创建
#include <windows.h>
#include <iostream.h>
DWORD WINAPI Fun1Proc(
LPVOID lpParameter //thread data
);
int index=0;
void main()
{
HANDLE hthread1;
hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
CloseHandle(hThread1); //在主线程关闭这个线程的句柄,递减这个线程内核对象的使用计数
while(index++<1000)
cout<<"main thread is running"<<endl;
// Sleep(10);
/*使主线程暂停运行10ms,防止因主线程退出导致进程结束而回收进程资源,使线程也结束(这里windows线程相当于java里的守护线程,一旦main主线程退出,其它线程就结束) */
}
DWORD WINAPI Fun1Proc(
LPVOID lpParameter //thread data
)
{
while(index++<1000)
cout<<"thread1 is running"<<endl;//在单CPU下,主线程与thread1交替运行
return 0;
}
------------------------------
例2 模拟火车站售票系统(互斥对象的讲解;采用互斥对象来实现多线程的同步)
#include <windows.h>
#include <iostream.h>
DWORD WINAPI Fun1Proc(
LPVOID lpParameter //thread data
);
DWORD WINAPI Fun2Proc(
LPVOID lpParameter //thread data
);
int index=0;
int tickets=100;//总票数
HANDLE hMutex;//将互斥对象句柄声明为全局的
void main()
{
HANDLE hthread1;
HANDLE hthread2;
hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
CloseHandle(hThread1); //在主线程关闭这个线程的句柄,递减这个线程内核对象的使用计数
/*while(index++<1000)
cout<<"main thread is running"<<endl; */
hMutex=CreateMutex(NULL,FALSE,NULL);//创建一个匿名互斥对象
/*注:若将这里改为hMutex=CreateMutex(NULL,TRUE,NULL)主线程main将拥有互斥对象,使互斥对象的计数器增为1(对应拥有的ID为主线程ID),但主线程并没有释放,所以Thread1和Thread2将一直等待不能行,知道主线程Sleep(4000)结束,进程退出(同时,由于在主线程中创建互斥对象的时候,操作系统同时会将主线程的ID号赋给互斥对象hMutex的ID,于是在Thread1和Thread2中想在WaitForSingleObject之前使用ReleaseMutex也是无用的,因为操作系统会先判断当前线程ID和互斥对象的ID是否相等,所以不能释放互斥对象,所以加入下面一句:ReleasehMutex(hMutex)。若在这ReleasehMutex前又WaitForSingleObject(hMutex,INFINITE),那么因为ID一样,所以WaitForSingleObject可以使计数器又增1变为2,所以要ReleaseMutex两次才能变为0,所以要再加一句ReleasehMutex(hMutex))。总之,对每个线程,请求拥有多少次互斥对象,就要释放多少次。*/
Sleep(4000);
}
DWORD WINAPI Fun1Proc(
LPVOID lpParameter //thread data
)
{
/*while(index++<1000)
cout<<"thread1 is running"<<endl;//在单CPU下,主线程与thread1交替运行*/
while(TRUE)
{
//ReleaseMutex(hMutex);
//无限等待,直到所等待的互斥信号hMutex变为有信号状态才继续往下运行
WaitForSingleObject(hMutex,INFINITE);
if(tickets>0)
cout<<"thread1 sell ticket:"<<tickets--<<endl;
else
break;
ReleaseMutex(hMutex);//释放互斥对象
}
return 0;
}
DWORD WINAPI Fun2Proc(
LPVOID lpParameter //thread data
)
{
while(TRUE)
{
//ReleaseMutex(hMutex);
WaitForSingleObject(hMutex,INFINITE);
if(tickets>0)
cout<<"thread2 sell ticket:"<<tickets--<<endl;
else
break;
ReleaseMutex(hMutex);//释放互斥对象
}
return 0;
}
-------------------------------
例3 操作系统维护了线程及其相关的互斥对象的信息
#include <windows.h>
#include <iostream.h>
DWORD WINAPI Fun1Proc(
LPVOID lpParameter //thread data
);
DWORD WINAPI Fun2Proc(
LPVOID lpParameter //thread data
);
int index=0;
int tickets=100;//总票数
HANDLE hMutex;//将互斥对象句柄声明为全局的
void main()
{
HANDLE hthread1;
HANDLE hthread2;
hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
CloseHandle(hThread1); //在主线程关闭这个线程的句柄,递减这个线程内核对象的使用计数
hMutex=CreateMutex(NULL,FALSE,NULL);//创建一个匿名互斥对象
Sleep(4000);
}
DWORD WINAPI Fun1Proc(
LPVOID lpParameter //thread data
)
{
WaitForSingleObject(hMutex,INFINITE);
cout<<"thread1 is running"<<endl;
/*这里Thread1没有调用ReleaseMutex去释放互斥对象,但还是可以运行Thread2,因为,当Thread1不是while循环的,当Thread1执行完毕,操作系统会自动回收Thread1线程拥有的互斥对象,使hMutex的ID和计数器都归为0,因为操作系统维护了线程及其相关的互斥对象的信息。但hMutex保护的代码将不可知,程序将是不安全的。*/
return 0;
}
DWORD WINAPI Fun2Proc(
LPVOID lpParameter //thread data
)
{
WsitforSingleObject(hMutex,INFINITE);
cout<<"thread2 is running"<<endl;
return 0;
}
----------------------------
例4 利用命名互斥对象保证应用程序只有一个实例运行
#include <windows.h>
#include <iostream.h>
DWORD WINAPI Fun1Proc(
LPVOID lpParameter //thread data
);
DWORD WINAPI Fun2Proc(
LPVOID lpParameter //thread data
);
int index=0;
int tickets=100;//总票数
HANDLE hMutex;//将互斥对象句柄声明为全局的
void main()
{
HANDLE hthread1;
HANDLE hthread2;
hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
CloseHandle(hThread1); //在主线程关闭这个线程的句柄,递减这个线程内核对象的使用计数
hMutex=CreateMutex(NULL,TRUE,"tickets");
if(hMutex)
{
if(ERROR_ALREADY_EXISTS==GetLastError())
{
cout<<"only instance can run!"<<endl;
return;
/*利用创建互斥对象hMutex的返回值,可以保证应用程序只能运行一个实例,比如平常用的“金山词霸”就只能跑一个实例。*/
}
}
Sleep(4000);
}
DWORD WINAPI Fun1Proc(
LPVOID lpParameter //thread data
)
{
WaitForSingleObject(hMutex,INFINITE);
cout<<"thread1 is running"<<endl;
return 0;
}
DWORD WINAPI Fun2Proc(
LPVOID lpParameter //thread data
)
{
WsitforSingleObject(hMutex,INFINITE);
cout<<"thread2 is running"<<endl;
return 0;
}
- windows多线程(sunxin vc++ 笔记2)
- windows多线程同步--事件对象(sunxin vc++ 笔记3)
- windows多线程-关键代码段(临界区)(sunxin vc++ 笔记4)
- windows消息机制-基础(sunxin vc++ 笔记1)
- 重温sunxin的VC++深入详解笔记(一)
- Windows程序内部运行原理 - 孙鑫 - VC++6.0 - Code by SunXin/Remark by HackerJLY
- windows vc多线程
- VC----Windows多线程
- 对VC++一些常见问题的整理(www.sunxin.org)
- VC学习笔记10多线程
- WINDOWS多线程学习笔记
- sunxin-DC
- sunxin-绘图
- VC windows api 多线程---互斥量、信号量、临界值
- VC windows api 多线程---临界区
- VC WINDOWS 程序设计学习笔记
- VC多线程编程2
- VC多线程编程学习笔记(一)
- 马云给雅虎员工作的精彩演讲:爱迪生欺骗了世界!
- Transport dt_socket failed to initialize, rc = 509
- 第 1 章 面向 Visual Basic开发人员的 Microsoft .NET Framework入门指南
- 存储过程动态配直3
- 今天无事可说
- windows多线程(sunxin vc++ 笔记2)
- 【转贴】无间道中的博弈!
- 权限管理 how to control the authorization?
- 深入理解和使用Windows NT驱动程序的执行上下文(一)
- zip版本Tomcat配置新手入门
- 用.net compact framework开发pda程序
- 测试驱动经验
- 主题:瑞萨16 位R8C/TINY 系列单片机
- 用Avalon建立未来的Windows用户界面