剑指offer-算法题练习:part14 c++多线程—2个线程并发售票系统-烽火众智
如果遇到“CreateMutexW”: 不能将参数 3 从“const char [8]”转换为“LPCWSTR”的错误,可以在vs中将项目的字符集,从“使用unicode字符集”改为“使用多字节字符集”。
#include <windows.h>
#include <iostream.h>
using namespace std;
DWORD WINAPI Fun1Proc(LPVOID lpParameter);//thread data线程1声明
DWORD WINAPI Fun2Proc(LPVOID lpParameter);//thread data线程2声明
int index=0;//定义一个变量用来控制循环,(在主线程中被注释了,所以这个参数没用上)
int tickets=10;//定义票的总数
HANDLE hMutex;
//线程1的入口函数
DWORD WINAPI Fun1Proc(LPVOID lpParameter)//thread data
{
while (true)
{
ReleaseMutex(hMutex);
WaitForSingleObject(hMutex,INFINITE);
if (tickets>0)
{
Sleep(1);
cout<<"thread1 sell ticket :"<<tickets--<<endl;
}
else
break;
ReleaseMutex(hMutex);
}
return 0;
}
//线程2的入口函数
DWORD WINAPI Fun2Proc(LPVOID lpParameter)//thread data
{
while (true)
{
ReleaseMutex(hMutex);
WaitForSingleObject(hMutex,INFINITE);
if (tickets>0)
{
Sleep(1);
cout<<"thread2 sell ticket :"<<tickets--<<endl;
}
else
break;
ReleaseMutex(hMutex);
}
return 0;
}
//主线程的入口函数
void main()
{
HANDLE hThread1;//定义一个句柄,在main函数中创建一个新的线程,要创建一个线程可以利用系统给我们提供的API函数CreateThread
HANDLE hThread2;//创建第二个线程
//创建线程
hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);//Fun1Proc线程入口函数的地址
hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);//将线程2的地址加入主线程中
CloseHandle(hThread1);//关闭线程1句柄
CloseHandle(hThread2);//关闭线程2句柄
//while(index++<1000) //当index小于1000的时候执行
//cout<<"main thread is running!"<<endl;//输出一行字,表明是主线程在运行
//Sleep(10); //让主线程停止执行,即这10毫秒内主线程放弃执行的权利,运行发现两个都运行了,下面要让主线程和线程1不断的交替运行,我们可以做一个循环
//创建互斥对象
hMutex=CreateMutex(NULL,TRUE,"tickets");//给这个互斥对象取名 将中间的设置为TRUE
//创建互斥对象,FALSE(表示主线程不拥有) 将它的ID设置为空,
//即此时谁都没有拥有这个线程ID,系统会自动设为0,处于有信号状态,继续向下执行,
//如果这里设置为TRUE,那么主线程拥有互斥对象此时计数器记录为1,调用一个ReleaseMutex释放之后计数器又记录为0,
//此时信号处于可用状态,其他的线程可以使用,每申请一次就加1,释放就减1,为0则可用
//如果我们将最后一个NULL(没有名字)去掉,并且给这个互斥对象取名
if (hMutex)//判断对象是否已经存在,如果存在就执行下面的
{
if (ERROR_ALREADY_EXISTS==GetLastError())判断实例是否正在运行
{
cout<<"only one instance can run!"<<endl;
return;
}
}
WaitForSingleObject(hMutex,INFINITE);
ReleaseMutex(hMutex);//释放主线程互斥对象,在10s内连开多个实例只有第一个可以顺利运行,这就是互斥对象的用法
ReleaseMutex(hMutex);
Sleep(4000);//让主线程睡眠4秒,这个时间必须设置合理,不然线程1、2没运行完就关了进程
}