1.创建事件对象
#include <iostream>
#include <windows.h>
using namespace std;
DWORD WINAPI thread1fun(LPVOID);
DWORD WINAPI thread2fun(LPVOID);
int tickets=10;
HANDLE hEvent;
int main()
{
HANDLE hthread1,hthread2;
the third parameter: 指定事件对象的初始状态。
/// 如果为TRUE,初始状态为有信号状态; FALSE:为无信号状态。
/// the second parameter: TRUE:人工重置,否则自动重置无信号状态
hEvent=CreateEvent(NULL,FALSE,FALSE,"tickets");
if(hEvent)
{
if(ERROR_ALREADY_EXISTS==GetLastError()) //当前有实例在
{
cout<<"only instance can run\n";
}
}
SetEvent(hEvent); ///set 有信号状态
hthread1=CreateThread(NULL,0,thread1fun,NULL,0,NULL);
// Sleep(11);
hthread2=CreateThread(NULL,0,thread2fun,NULL,0,NULL);
CloseHandle(hthread1);
CloseHandle(hthread2);
// while(1)
Sleep(4000);
CloseHandle(hEvent);
return 0;
}
DWORD WINAPI thread1fun(LPVOID lpParameter)
{
while(1)
{ ///请求到信号,系统自动重置为无信号状态
WaitForSingleObject(hEvent,INFINITE);
if(tickets>0)
{
Sleep(10);
cout<<"thread 1: "<<tickets--<<endl;
}
else
break;
SetEvent(hEvent); //set 有信号状态
}
return 0;
}
DWORD WINAPI thread2fun(LPVOID lpParameter)
{
while(1)
{
WaitForSingleObject(hEvent,INFINITE); /请求到信号,系统重置为无信号状态
if(tickets>0)
{
Sleep(10);
cout<<"thread 2: "<<tickets--<<endl;
}
else
break;
SetEvent(hEvent); set 有信号状态
}
return 0;
}
2.创建互斥对象
#include <iostream>
#include <windows.h>
using namespace std;
DWORD WINAPI thread1fun(LPVOID);
DWORD WINAPI thread2fun(LPVOID);
int tickets=100;
HANDLE hMutex;
int main()
{
HANDLE hthread1,hthread2;
hMutex=CreateMutex(NULL,FALSE,"tickets"); ///TRUE :main thread got mutex object
hthread1=CreateThread(NULL,0,thread1fun,NULL,0,NULL);
// Sleep(11);
hthread2=CreateThread(NULL,0,thread2fun,NULL,0,NULL);
CloseHandle(hthread1);
CloseHandle(hthread2);
if(hMutex)
{
if(ERROR_ALREADY_EXISTS==GetLastError())
{
cout<<"only instance can run!"<<endl;
return 0;
}
}
Sleep(4000);
while(1)
{
Sleep(10);
}
return 0;
}
DWORD WINAPI thread1fun(LPVOID lpParameter)
{
while(1)
{
WaitForSingleObject(hMutex,INFINITE);
if(tickets>0)
{
Sleep(10);
cout<<"thread 1: "<<tickets--<<endl;
}
else
break;
ReleaseMutex(hMutex); //释放当前线程ID,互斥对象计数器-1
} //谁拥有互斥对象,你可以释放
return 0;
}
DWORD WINAPI thread2fun(LPVOID lpParameter)
{
while(1)
{
WaitForSingleObject(hMutex,INFINITE);
if(tickets>0)
{
Sleep(10);
cout<<"thread 2: "<<tickets--<<endl;
}
else
break;
ReleaseMutex(hMutex);
}
return 0;
}
3.利用关键代码段
#include <iostream>
#include <windows.h>
using namespace std;
DWORD WINAPI thread1fun(LPVOID);
DWORD WINAPI thread2fun(LPVOID);
int tickets=20;
CRITICAL_SECTION g_cs; /*---
每个线程中访问临界资源的那段程序称为临界区(Critical Section)
(临界资源是一次仅允许一个线程使用的共享资源)。
每次只准许一个线程进入临界区,进入后不允许其他线程进入。
不论是硬件临界资源,还是软件临界资源,多个线程必须互斥地对它进行访问.
------------------**/
int main()
{
HANDLE hthread1,hthread2;
InitializeCriticalSection(&g_cs);
hthread1=CreateThread(NULL,0,thread1fun,NULL,0,NULL);
// Sleep(11);
hthread2=CreateThread(NULL,0,thread2fun,NULL,0,NULL);
CloseHandle(hthread1);
CloseHandle(hthread2);
// while(1)
Sleep(4000);
DeleteCriticalSection(&g_cs);
return 0;
}
DWORD WINAPI thread1fun(LPVOID lpParameter)
{
while(1)
{
EnterCriticalSection(&g_cs); //进入关键代码段
if(tickets>0)
{
Sleep(10);
cout<<"thread 1: "<<tickets--<<endl;
}
else
break;
LeaveCriticalSection(&g_cs);//释放临界区对象所有权
}
return 0;
}
DWORD WINAPI thread2fun(LPVOID lpParameter)
{
while(1)
{
EnterCriticalSection(&g_cs); /请求到信号,系统重置为无信号状态
if(tickets>0)
{
Sleep(10);
cout<<"thread 2: "<<tickets--<<endl;
}
else
break;
LeaveCriticalSection(&g_cs);
}
return 0;
}
4,关键代码段造成的线程锁死
///线程锁死
#include <iostream>
#include <windows.h>
using namespace std;
DWORD WINAPI thread1fun(LPVOID);
DWORD WINAPI thread2fun(LPVOID);
int tickets=20;
CRITICAL_SECTION g_csA;
CRITICAL_SECTION g_csB;
int main()
{
HANDLE hthread1,hthread2;
InitializeCriticalSection(&g_csA);
InitializeCriticalSection(&g_csB);
hthread1=CreateThread(NULL,0,thread1fun,NULL,0,NULL);
// Sleep(11);
hthread2=CreateThread(NULL,0,thread2fun,NULL,0,NULL);
CloseHandle(hthread1);
CloseHandle(hthread2);
// while(1)
Sleep(4000);
DeleteCriticalSection(&g_csA);
DeleteCriticalSection(&g_csB);
return 0;
}
DWORD WINAPI thread1fun(LPVOID lpParameter)
{
while(1)
{
EnterCriticalSection(&g_csA); //进入关键代码段A
Sleep(1); //B
EnterCriticalSection(&g_csB); //等待B所有权
if(tickets>0)
{
Sleep(10);
cout<<"thread 1: "<<tickets--<<endl;
}
else
break;
LeaveCriticalSection(&g_csA);//释放临界区对象所有权
LeaveCriticalSection(&g_csB);
}
return 0;
}
DWORD WINAPI thread2fun(LPVOID lpParameter)
{
while(1)
{
EnterCriticalSection(&g_csB); /请求到信号,系统重置为无信号状态
Sleep(1);
EnterCriticalSection(&g_csA); //等待A所有权
if(tickets>0)
{
Sleep(10);
cout<<"thread 2: "<<tickets--<<endl;
}
else
break;
LeaveCriticalSection(&g_csA);
LeaveCriticalSection(&g_csB);
}
return 0;
}