C++ 线程同步

1、临界区

用CRITICAL_SECTION结构对象保护共享资源。

用EnterCriticalSection()和LeaveCriticalSection()函数去标识和释放一个临界区。

所用到的CRITICAL_SECTION结构对象必须经过InitializeCriticalSection()的初始化后才能使用。

如果有多个线程试图同时访问临界区,那么在有一个线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占。

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

std::vector<int> a(5,0);
CRITICAL_SECTION g_Critical;

DWORD WINAPI ThreadProc1(PVOID pParam);
DWORD WINAPI ThreadProc2(PVOID pParam);
int main()
{
	InitializeCriticalSection(&g_Critical);

	CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);
	CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);
	
	system("pause");
	return 0;
}

DWORD WINAPI ThreadProc1(PVOID pParam)
{//给vector赋值
	EnterCriticalSection(&g_Critical);
	a = { 1,2,3,4,5 };
	LeaveCriticalSection(&g_Critical);
	return 0;
}

DWORD WINAPI ThreadProc2(PVOID pParam)
{//打印vector的值
	EnterCriticalSection(&g_Critical);
	for (auto i = a.begin() ; i != a.end() ; i++)
	{
		std::cout << *i;
		Sleep(10);
	}
	LeaveCriticalSection(&g_Critical);
	return 0;
}

2、事件

HANDLE CreateEventA( LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCSTR lpName );

第二个参数如果为TRUE,该对象需要使用ResetEvent函数将事件状态设置为非信号状态。如果设置为FALSE,当一个线程等待到事件信号后系统会自动将事件状态复原为无信号状态。

第三个参数表示初始状态,为TRUE则有信号,为FALSE则无信号

第四个参数是名字。

可以使用WaitForSingleObject进行等待

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

int x = 0;
HANDLE g_hEvent;

DWORD WINAPI ThreadProc1(PVOID pParam);
DWORD WINAPI ThreadProc2(PVOID pParam);
int main()
{
	g_hEvent = CreateEvent(NULL, TRUE, FALSE, TEXT("Test"));

	CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);
	CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);
	
	system("pause");
	return 0;
}

DWORD WINAPI ThreadProc1(PVOID pParam)
{
	DWORD dwReturn = WaitForSingleObject(g_hEvent, INFINITE);
	if (dwReturn == WAIT_OBJECT_0)
	{
		x++;
		std::cout << "this is thread1,x = ";
		std::cout << x << std::endl;
		ResetEvent(g_hEvent);
	}
	return 0;
}
DWORD WINAPI ThreadProc2(PVOID pParam)
{
	//Sleep(10);
	x++;
	std::cout << "this is thread2,x = ";
	std::cout << x << std::endl;	
	SetEvent(g_hEvent);
	return 0;
}

3、信号量

主要是两个函数

创建信号量:

CreateSemaphore( 
  _In_opt_  LPSECURITY_ATTRIBUTES lpSemaphoreAttributes  //安全属性
  _In_      LONG lInitialCount,    //初始资源数
  _In_      LONG lMaximumCount,    //最大资源数
  _In_opt_  LPCTSTR lpName     //名字
); 

释放信号量,会增加信号量计数

BOOL WINAPI ReleaseSemaphore(
   HANDLE hSemaphore,   //信号量句柄
   LONG lReleaseCount, //当前资源数增加数量
   LPLONG lpPreviousCount  //增加前的数量
   );

例子:

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

int x = 0;
HANDLE g_Semaphore;

DWORD WINAPI ThreadProc1(PVOID pParam);
DWORD WINAPI ThreadProc2(PVOID pParam);
int main()
{
	g_Semaphore = CreateSemaphore(NULL, 1, 2, TEXT("test"));

	CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);
	CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);

	Sleep(100);
	
	system("pause");
	return 0;
}

DWORD WINAPI ThreadProc1(PVOID pParam)
{
	while (x < 10)
	{
		DWORD dwReturn = WaitForSingleObject(g_Semaphore, INFINITE);
		if (dwReturn == WAIT_OBJECT_0)
		{
			x++;
			std::cout << "this is thread1,x = ";
			std::cout << x << std::endl;
			long count;
			ReleaseSemaphore(g_Semaphore, 1, &count);
		}
	}

	return 0;
}
DWORD WINAPI ThreadProc2(PVOID pParam)
{
	//Sleep(10);
	while (x < 10)
	{
		DWORD dwReturn = WaitForSingleObject(g_Semaphore, INFINITE);
		if (dwReturn == WAIT_OBJECT_0)
		{
			x++;
			std::cout << "this is thread2,x = ";
			std::cout << x << std::endl;
			long count;
			ReleaseSemaphore(g_Semaphore, 1, &count);
		}
	}
	
	return 0;
}

4、互斥量

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

int x = 0;
HANDLE g_Mutex;

DWORD WINAPI ThreadProc1(PVOID pParam);
DWORD WINAPI ThreadProc2(PVOID pParam);
int main()
{
	g_Mutex = CreateMutex(NULL, FALSE, TEXT("test"));

	CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);
	CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);

	Sleep(200);
	
	system("pause");
	return 0;
}

DWORD WINAPI ThreadProc1(PVOID pParam)
{
	while (x < 10)
	{
		DWORD dwReturn = WaitForSingleObject(g_Mutex, INFINITE);
		if (dwReturn == WAIT_OBJECT_0)
		{
			x++;
			std::cout << "this is thread1,x = ";
			std::cout << x << std::endl;
			Sleep(10);
			ReleaseMutex(g_Mutex);
		}
	}

	return 0;
}
DWORD WINAPI ThreadProc2(PVOID pParam)
{
	//Sleep(10);
	while (x < 10)
	{
		DWORD dwReturn = WaitForSingleObject(g_Mutex, INFINITE);
		if (dwReturn == WAIT_OBJECT_0)
		{
			x++;
			std::cout << "this is thread2,x = ";
			std::cout << x << std::endl;
			Sleep(10);
			ReleaseMutex(g_Mutex);
		}
	}
	
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值