多线程
例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;
}