解决多线程访问数据共享问题

问题原因:由于多线程访问造成数据不统一导致的。

测试案例代码:

code:

// 全局资源
DWORD dwArray[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
DWORD *pdwArray[10];

// 资源调用函数
void printArray(const char* szpThradName)
{

	for (int i = 0; i<10; i++)
	{
		DbgPrintMine("%s  ==  %d\r\n", szpThradName, *pdwArray[i]);
		Sleep(1000);
	}

}


DWORD WINAPI ChildThread()
{

	while (true)
	{
		memset(pdwArray, NULL, sizeof(dwArray));
		for (int i = 0; i < 10; i++)
		{
			pdwArray[i] = dwArray + i;
		}
		printArray("子线程");
	}
	return 0;
}

DWORD WINAPI MainThread()
{

	while (true)
	{
		memset(pdwArray, NULL, sizeof(dwArray));
		for (int i = 0; i< 10; i++)
		{
			pdwArray[i] = dwArray + i;
			Sleep(700);
		}
		printArray("主线程");
	}
	return 0;
}


void CTestoneDlg::OnBnClickedButtonMainthread()
{
	// TODO: 在此添加控件通知处理程序代码
	CreateThread(NULL, NULL, LPTHREAD_START_ROUTINE(MainThread), NULL, NULL, NULL);
}


void CTestoneDlg::OnBnClickedButtonChildthread()
{
	// TODO: 在此添加控件通知处理程序代码
	CreateThread(NULL, NULL, LPTHREAD_START_ROUTINE(ChildThread), NULL, NULL, NULL);
}

造成原因:两个线程访问的数据未同步。

解决方式:
1、事件临界区(临界资源:一次仅允许一个进程使用的资源称为临界资源)
就是使原先多个进程同时访问的数据每次仅允许一个进程访问,各进程对这个数据的访问时互斥的。
2、HOOK窗口事件

Windwos API
InitializeCriticalSection ----> 初始化一个临界资源对象
VOID InitializeCriticalSection(
LPCRITICAL_SECTION lpCriticalSection // address of critical
// section object
);

code:

// 全局资源
DWORD dwArray[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
DWORD *pdwArray[10];

// 临界区对象
CRITICAL_SECTION mySection;


// 资源调用函数
void printArray(const char* szpThradName)
{
	// 添加临界区
	EnterCriticalSection(&mySection);
	for (int i = 0; i<10; i++)
	{
		DbgPrintMine("%s  ==  %d\r\n", szpThradName, *pdwArray[i]);
		Sleep(1000);
	}
	// 退出临界区
	LeaveCriticalSection(&mySection);

}


DWORD WINAPI ChildThread()
{

	while (true)
	{
		EnterCriticalSection(&mySection);
		memset(pdwArray, NULL, sizeof(dwArray));
		for (int i = 0; i < 10; i++)
		{
			pdwArray[i] = dwArray + i;
		}
		printArray("子线程");
		LeaveCriticalSection(&mySection);
	}
	return 0;
}

DWORD WINAPI MainThread()
{

	while (true)
	{
		EnterCriticalSection(&mySection);
		memset(pdwArray, NULL, sizeof(dwArray));
		for (int i = 0; i< 10; i++)
		{
			pdwArray[i] = dwArray + i;
			Sleep(300);
		}
		printArray("主线程");
		LeaveCriticalSection(&mySection);
		Sleep(1000);
	}
	return 0;
}


void CTestoneDlg::OnBnClickedButtonMainthread()
{
	// TODO: 在此添加控件通知处理程序代码
	CreateThread(NULL, NULL, LPTHREAD_START_ROUTINE(MainThread), NULL, NULL, NULL);
}


void CTestoneDlg::OnBnClickedButtonChildthread()
{
	// TODO: 在此添加控件通知处理程序代码
	CreateThread(NULL, NULL, LPTHREAD_START_ROUTINE(ChildThread), NULL, NULL, NULL);
}


void CTestoneDlg::OnBnClickedButtonInit()
{
	// TODO: 在此添加控件通知处理程序代码
	// 初始化临界区
	InitializeCriticalSection(&mySection);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值