线程同步2021-09-26

线程同步


一、CriticalSection(关键代码段)

只能用于同一个进程中的多线程同步,效率高,速度快。它并不是核心对象,不是属于操作系统维护的,而是属于进程维护的。
CRITICAL_SECTION 结构体
主要函数:
//初始化
void InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
//进入关键代码段
void EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
//离开关键代码段
void LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
//销毁关键代码段
void DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
代码如下(示例):

#include <iostream>
#include <Windows.h>
using namespace std;
CRITICAL_SECTION g_cs;		//关键代码段
DWORD WINAPI ThreadFun1(LPVOID lpParameter);
DWORD WINAPI ThreadFun2(LPVOID lpParameter);
int g_resource = 100;

int main()
{
	InitializeCriticalSection(&g_cs);			//初始化关键代码段
	HANDLE hThread1 = CreateThread(0, 0, ThreadFun1, 0, 0, 0);
	HANDLE hThread2 = CreateThread(0, 0, ThreadFun2, 0, 0, 0);
	CloseHandle(hThread1);
	CloseHandle(hThread2);
	Sleep(1000);
	return 0;
}

DWORD __stdcall ThreadFun1(LPVOID lpParameter)
{
	while (1)
	{
		EnterCriticalSection(&g_cs);
		if (g_resource <= 0)
		{
			LeaveCriticalSection(&g_cs);
			break;
		}
		else
		{
			cout << "ThreadFun1 used :" << g_resource-- << endl;
			LeaveCriticalSection(&g_cs);
			Sleep(1);		//除了等待之外,还会放弃当前的执行权限
		}
	}
	return 0;
}

DWORD __stdcall ThreadFun2(LPVOID lpParameter)
{
	//同ThreadFun1
}

二、Mutex(互斥对象)

用法同CriticalSection相似,可用于不同进程之间的同步,也可用于防止同一个程序多次运行
Mutex
HANDLE WINAPI CreateMutex(
In_opt LPSECURITY_ATTRIBUTES lpMutexAttributes,
In BOOL bInitialOwner, //创建该对象的线程是否拥有它
In_opt LPCTSTR lpName //互斥对象的名
);
主要函数:
WaitForSingleObject(); //等待一个对象
//打开互斥对象
HANDLE OpenMutex(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
LPCTSTR lpName //名称
);
//结束访问
BOOL ReleaseMutex (HANDLE hMutex);
代码如下(示例):

#include <iostream>
#include <Windows.h>
using namespace std;
HANDLE g_hMutex;		//互斥对象
DWORD WINAPI ThreadFun1(LPVOID lpParameter);
DWORD WINAPI ThreadFun2(LPVOID lpParameter);
int g_resource = 100;

int main()
{
	//当前线程拥有对象
	//g_hMutex = CreateMutex(0, true, 0);
	//ReleaseMutex(g_hMutex);
	g_hMutex = CreateMutex(0, false, 0);
	HANDLE hThread1 = CreateThread(0, 0, ThreadFun1, 0, 0, 0);
	HANDLE hThread2 = CreateThread(0, 0, ThreadFun2, 0, 0, 0);
	CloseHandle(hThread1);
	CloseHandle(hThread2);
	Sleep(1000);
	return 0;
}
DWORD __stdcall ThreadFun1(LPVOID lpParameter)
{
	while (1)
	{
		WaitForSingleObject(g_hMutex, INFINITE);
		if (g_resource <= 0)
		{
			ReleaseMutex(g_hMutex);
			break;
		}
		else
		{
			cout << "ThreadFun1 used :" << g_resource-- << endl;
			ReleaseMutex(g_hMutex);
			Sleep(1);		//除了等待之外,还会放弃当前的执行权限
		}
	}
	return 0;
}
DWORD __stdcall ThreadFun2(LPVOID lpParameter)
{
	//同ThreadFun1
}

三、Event(事件对象)

HANDLE WINAPI CreateEvent(
In_opt LPSECURITY_ATTRIBUTES lpEventAttributes,
In BOOL bManualReset, //手动重置,还是自动重置 (重置为无信号状态)
In BOOL bInitialState, //初始的信号状态
In_opt LPCTSTR lpName
);
部分函数:
ResetEvent //将事件对象设置为无信号状态
SetEvent //将事件对象设置为有信号状态
WaitForSingleObject(); //等待一个对象
代码如下(示例):

#include <iostream>
#include <Windows.h>
using namespace std;
HANDLE g_hEvent;		//互斥事件
DWORD WINAPI ThreadFun1(LPVOID lpParameter);
DWORD WINAPI ThreadFun2(LPVOID lpParameter);
int g_resource = 100;

int main()
{
	//					   手动重置,初始无信号
	g_hEvent = CreateEvent(0, true, false, 0);
	//设为有信号
	SetEvent(g_hEvent);
	HANDLE hThread1 = CreateThread(0, 0, ThreadFun1, 0, 0, 0);
	HANDLE hThread2 = CreateThread(0, 0, ThreadFun2, 0, 0, 0);
	CloseHandle(hThread1);
	CloseHandle(hThread2);
	Sleep(1000);
	return 0;
}

DWORD __stdcall ThreadFun1(LPVOID lpParameter)
{
	while (1)
	{
		WaitForSingleObject(g_hEvent, INFINITE);
		ResetEvent(g_hEvent);
		if (g_resource <= 0)
		{
			SetEvent(g_hEvent);
			break;
		}
		else
		{
			cout << "ThreadFun1 used :" << g_resource-- << endl;
			SetEvent(g_hEvent);
			Sleep(1);		//除了等待之外,还会放弃当前的执行权限
		}
	}
	return 0;
}
DWORD __stdcall ThreadFun2(LPVOID lpParameter)
{
	//同ThreadFun1
}

四、Interlocked(原子锁)

部分函数:
InterlockedIncrement(); //自加
InterlockedDecrement(); //自减
InterlockedOr(); //或
InterlockedAnd //与
等等…

五、信号量

CreateSemaphore();//创建
ReleaseSemaphore();//释放信号

总结

关于线程同步,异步相关的只是还有待进一步发掘@_@


版权声明:本文为qq_45523131原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。