Windows核心编程:第8章 用户模式下的线程同步

Github

https://github.com/gongluck/Windows-Core-Program.git

//第8章 用户模式下的线程同步.cpp: 定义应用程序的入口点。
//

#include "stdafx.h"
#include "第8章 用户模式下的线程同步.h"

LONG g_i = 100;
LONG g_b = FALSE;

CRITICAL_SECTION g_cs; //关键段
SRWLOCK g_rw; //读写锁
CONDITION_VARIABLE g_cv; //条件变量


DWORD WINAPI Thread1(PVOID param)
{
	for (int i = 0; i < 100; ++i)
	{
		EnterCriticalSection(&g_cs);
		g_i += i;
		LeaveCriticalSection(&g_cs);
	}
	return 0;
}

DWORD WINAPI Thread2(PVOID param)
{
	for (int i = 0; i < 100; ++i)
	{
		if (TryEnterCriticalSection(&g_cs))
		{
			g_i += i;
			LeaveCriticalSection(&g_cs);
		}
		else
			SwitchToThread();
	}
	return 0;
}

DWORD WINAPI Thread3(PVOID param)
{
	for (int i = 0; i < 100; ++i)
	{
		AcquireSRWLockExclusive(&g_rw);
		//写
		OutputDebugString(TEXT("------------AcquireSRWLockExclusive succeed.\n"));
		ReleaseSRWLockExclusive(&g_rw);
	}
	return 0;
}

DWORD WINAPI Thread4(PVOID param)
{
	for (int i = 0; i < 100; ++i)
	{
		AcquireSRWLockShared(&g_rw);
		//读
		OutputDebugString(TEXT("------------AcquireSRWLockShared succeed.\n"));
		ReleaseSRWLockShared(&g_rw);
	}
	return 0;
}

DWORD WINAPI Thread5(PVOID param)
{
	int n = 0;
	for (int i = 0; i < 100; ++i)
	{
		EnterCriticalSection(&g_cs);
		++n;
		if (n >= 100)
			break;
		if(g_i <= 0)
			SleepConditionVariableCS(&g_cv, &g_cs, INFINITE); //解锁等待条件变量,返回时再加锁
		g_i--;
		LeaveCriticalSection(&g_cs);
	}
	return 0;
}

DWORD WINAPI Thread6(PVOID param)
{
	for (int i = 0; i < 100; ++i)
	{
		if (TryEnterCriticalSection(&g_cs))
		{
			g_i++;
			WakeConditionVariable(&g_cv); //唤醒等待条件变量的线程
			LeaveCriticalSection(&g_cs);
		}
		else
			SwitchToThread();
	}
	return 0;
}

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
	_In_opt_ HINSTANCE hPrevInstance,
	_In_ LPWSTR    lpCmdLine,
	_In_ int       nCmdShow)
{
	//原子操作Interlocked系列
	LONG newl = InterlockedAdd(&g_i, 1);
	LONG oldl = InterlockedExchange(&g_i, 10);
	oldl = InterlockedCompareExchange(&g_i, 100, 10);
	LONGLONG oldll = InterlockedAnd(&g_i, 0x0001);

	//旋转锁!
	while (InterlockedExchange(&g_b, TRUE) == TRUE)
		Sleep(0);

	//使用关键段
	//InitializeCriticalSection(&g_cs);
	BOOL bret = InitializeCriticalSectionAndSpinCount(&g_cs, 1);//初始化关键段并用上旋转锁
	oldl = SetCriticalSectionSpinCount(&g_cs, 4000);
	g_i = 0;
	HANDLE hthread1 = CreateThread(nullptr, 0, Thread1, nullptr, 0, nullptr);
	HANDLE hthread2 = CreateThread(nullptr, 0, Thread2, nullptr, 0, nullptr);

	WaitForSingleObject(hthread1, INFINITE);
	WaitForSingleObject(hthread2, INFINITE);
	CloseHandle(hthread1);
	hthread1 = nullptr;
	CloseHandle(hthread2);
	hthread2 = nullptr;

	//使用读写锁
	InitializeSRWLock(&g_rw);
	HANDLE hthread3 = CreateThread(nullptr, 0, Thread3, nullptr, 0, nullptr);
	HANDLE hthread4 = CreateThread(nullptr, 0, Thread4, nullptr, 0, nullptr);

	WaitForSingleObject(hthread3, INFINITE);
	WaitForSingleObject(hthread4, INFINITE);
	CloseHandle(hthread3);
	hthread3 = nullptr;
	CloseHandle(hthread4);
	hthread4 = nullptr;

	//条件变量(误入锁?)
	InitializeConditionVariable(&g_cv);
	g_i = 0;
	HANDLE hthread5 = CreateThread(nullptr, 0, Thread5, nullptr, 0, nullptr);
	HANDLE hthread6 = CreateThread(nullptr, 0, Thread6, nullptr, 0, nullptr);

	WaitForSingleObject(hthread5, INFINITE);
	WaitForSingleObject(hthread6, INFINITE);
	CloseHandle(hthread5);
	hthread5 = nullptr;
	CloseHandle(hthread6);
	hthread6 = nullptr;

	DeleteCriticalSection(&g_cs);

	system("pause");
	return 0;
}
posted @ 2018-06-24 16:04  gongluck  阅读(214)  评论(0编辑  收藏  举报