孙鑫 VC++深入详解第16课——线程同步与异步套接字编程

时间:2020-12-08 21:13:06

1.通过事件对象实现同步

①创建事件对象CreateEvent

②设置为激活常态SetEvent

③等待信号量WaitForSingleObject

④关闭事件句柄CloseHandle

代码:

#include <Windows.h>
#include <iostream>

using namespace std;
int tickets = 100;

HANDLE g_Event;//事件对象句柄
DWORD WINAPI OneSellTickets(LPVOID lpParam);
DWORD WINAPI TwoSellTickets(LPVOID lpParam);
void main()
{
	//创建事件句柄,
	g_Event = CreateEvent(NULL,              //安全性,默认是NULL
						  FALSE,			 //FALSE表示线程释放后自动复位为无信号,TRUE要手动复位
						  FALSE,			 //TRUE表示有信号状态,FALSE表示无信号状态
						  TEXT("tickets"));
	if (g_Event)
	{
		if (ERROR_ALREADY_EXISTS == GetLastError())
		{
			cout<<"only one instance can run"<<endl;
			return ;
		}
	}
	SetEvent(g_Event);
	HANDLE handleOne = CreateThread(NULL,0,OneSellTickets,NULL,0,NULL);
	HANDLE handleTwo = CreateThread(NULL,0,TwoSellTickets,NULL,0,NULL);
    CloseHandle(handleOne);
	CloseHandle(handleTwo);

	Sleep(1000);
	
	CloseHandle(g_Event);

	cin.get();
	cin.get();
}

DWORD WINAPI OneSellTickets(LPVOID lpParam)
{
	while (TRUE)
	{
		WaitForSingleObject(g_Event,INFINITE);
		if (tickets > 0)
		{
			cout<<"One Sell Tickets"<<tickets--<<endl;
			SetEvent(g_Event);
		} 
		else
		{
			SetEvent(g_Event);
			break;
		}
	}
	return 0;
}

DWORD WINAPI TwoSellTickets(LPVOID lpParam)
{
	while (TRUE)
	{
		WaitForSingleObject(g_Event,INFINITE);
		if (tickets > 0)
		{
			cout<<"Two Sell Tickets"<<tickets-- <<endl;
			SetEvent(g_Event);
		} 
		else
		{
			SetEvent(g_Event);
			break;
		}
	}
	return 0;
}

2.临界区:

①设置临界区结构体 CRITICAL_SECTION

②初始化临界区 InitializeCriticalSection

③进入临界区 EnterCriticalSection

④离开临界区 LeaveCriticalSection

⑤销毁临界区 DeleteCriticalSection


#include <Windows.h>
#include <iostream>

using namespace std;
int tickets = 100;

CRITICAL_SECTION g_cs;//设置临界区结构体的全局变量

DWORD WINAPI OneSellTickets(LPVOID lpParam);
DWORD WINAPI TwoSellTickets(LPVOID lpParam);
void main()
{

	
	InitializeCriticalSection(&g_cs);
	HANDLE handleOne = CreateThread(NULL,0,OneSellTickets,NULL,0,NULL);
	HANDLE handleTwo = CreateThread(NULL,0,TwoSellTickets,NULL,0,NULL);
	CloseHandle(handleOne);
	CloseHandle(handleTwo);

	Sleep(1000);
	DeleteCriticalSection(&g_cs);
	cin.get();
	cin.get();
}

DWORD WINAPI OneSellTickets(LPVOID lpParam)
{
	while (TRUE)
	{
		EnterCriticalSection(&g_cs);
		if (tickets > 0)
		{
			cout<<"One Sell Tickets"<<tickets--<<endl;
			LeaveCriticalSection(&g_cs);
		} 
		else
		{
			LeaveCriticalSection(&g_cs);
			break;
		}
	}
	return 0;
}

DWORD WINAPI TwoSellTickets(LPVOID lpParam)
{
	while (TRUE)
	{
		EnterCriticalSection(&g_cs);
		if (tickets > 0)
		{
			cout<<"Two Sell Tickets"<<tickets-- <<endl;
			LeaveCriticalSection(&g_cs);
		} 
		else
		{
			LeaveCriticalSection(&g_cs);
			break;
		}
	}
	return 0;
}