#include<windows.h>
#include<iostream>
using namespace std;
DWORD WINAPI Fun1Proc(LPVOID lpParameter);
DWORD WINAPI Fun2Proc(LPVOID lpParameter);
int index = 0;
int tickets = 100;
void main()
{
HANDLE hThread1;
HANDLE hThread2;
hThread1 = CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
hThread2 = CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
CloseHandle(hThread1);
CloseHandle(hThread2);
Sleep(4000);
}
DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
while(TRUE)
{
if (tickets>0)
{
cout<<"thread1 sell ticket:"<<tickets--<<endl;
}else
{
break;
}
}
return 0;
}
DWORD WINAPI Fun2Proc(LPVOID lpParameter)
{
while(TRUE)
{
if (tickets>0)
{
cout<<"thread2 sell ticket:"<<tickets--<<endl;
}else
{
break;
}
}
return 0;
}
上述程序出现一问题,就是两个线程访问了同一个全局变量:tickets。为了避免这种问题的发生,就要求在多个线程之间进行一个同步处理,保证一个线程访问共享资源时,其它线程不能访问该资源。必须等到前者完成火车票的销售过程之后,其他线程才能访问该资源。
利用互斥对象实现线程同步。
互斥对象属于内核对象,它能够确保线程拥有对单个资源的互斥访问权。互斥对象包含一个使用数量,一个线程ID和一个计数器。其中ID用于标识系统中的哪个线程当前拥有互斥对象,计数器用于指明该线程拥有互斥对象的次数。创建互斥对象函数:
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes,//指向LPSECURITY_ATTRIBUTES的指针,可以传递NULL
BOOL bInitialOwner,//指定互斥对象初始的拥有者。为真时,则创建这个互斥对象的线程获得该对象的所有权,否则,该线程将不获得所创建的互斥对象的所有权
LPCTSTR lpName);//指定互斥对象的名称。如果此参数为NULL,则创建一个匿名的互斥对象
该函数可以创建或打开一个命名或匿名的互斥对象,然后程序就可以利用该互斥对象完成线程间的同步,如果调用成功,该函数返回所创建的互斥对象的句柄。如果创建的是命名的互斥对象,并且在CreateMutex函数调用之前,该命名的互斥对象存在,那么该函数将返回已经存在的这个互斥对象的句柄,而这时调用GetLastError函数将返回ERROR_ALREADY_EXISTS.另外,当线程对共享资源访问结束后,应释放该对象的所有权,也就是让该对象处于已通知状态。这时需要调用ReleaseMutex函数,该函数将释放指定对象的所有权,
BOOL ReleaseMutex(HANDLE hMutex)//hMutex为需要释放的互斥对象的句柄,调用成功,返回非0值,否则返回0值
原文:http://www.cnblogs.com/fenghuan/p/4863441.html