C++实战小项目贪吃蛇网游化框架搭建5多线程同步

从前面介绍的GAME类主体实现函数可以看出,整个游戏过程处于一个无限循环的过程中,为了保证游戏数据实时保存在服务端,在每一轮循环中都需要将更新的数据进行发送,这里本来可以直接在playgame函数体最后加上senddata函数实现这个功能,但为了学习应用下多线程技术,同时也可以将游戏进行过程中的通信部分与游戏部分分离开,以防止互相干扰,提高效率,因此新创建了一个线程专门用于发送游戏数据到服务端,定义线程函数:

HANDLE hSemaphore,h_event1,h_event2;
DWORD dwThreadId;
HANDLE hThread;

DWORD WINAPI ThreadFunc(LPVOID lpParam)
{
	DWORD waitresult;
	Game* temp = (Game*)lpParam;
	while (1) {
		if ((waitresult = WaitForSingleObject(hSemaphore, 0))==WAIT_OBJECT_0)
			break;
		WaitForSingleObject(h_event2, INFINITE);
		ResetEvent(h_event2);
		temp->senddata();
		SetEvent(h_event1);
	}
	return 0;
}

在游戏main函数中加入如下代码:


	h_event1 = CreateEvent(NULL, true, false, nullptr);
	h_event2 = CreateEvent(NULL, true, false, nullptr);
	hSemaphore = CreateSemaphore(NULL, 0, 1, NULL);//创建信号
	hThread = CreateThread(NULL, 0, ThreadFunc, (void*)&mygame, 0, &dwThreadId);

plyagame函数首端加入以下前两行代码,sleep前加入最后一行代码:

WaitForSingleObject(h_event1, INFINITE);
ResetEvent(h_event1);
SetEvent(h_event2);

在最初的多线程实现中,并未加入关于事件的代码,导致游戏运行过程中不时会报错,主要时由于多线程不同步的问题导致的,主线程部分会不断的改变snake类和相关类的数据,而senddata函数则需要读取相应的数据,如果在读取过程中,恰好主线程将相应数据进行了删除,则将出现读取不到数据的错误,因此之后加入了多线程同步的相关代码;
  多线程同步的实现方法有很多,这里主要采用了创建两个事件的方式进行,通信的线程在运行时,会等待主线程将event2激活,而主线程在运行到sleep之前时会激活event2,这样在主线程挂起时通信线程完成发送数据的操作,在通信良好的情况下,通信线程在主线程挂起期间完成发送数据并激活event1,这样主线程在进入下一轮循环时,接受到event1被激活的信号从而继续运行下面的代码,而若网络不好,则主线程会陷入停滞,这里还可以设置主线程等待事件,若等待时间过长则转入与用户相互的代码,这部分代码比较容易也就没有再写了。
  同时另外定义了一个semaphore,当游戏结束时该信号被激活,通知通信线程游戏已结束,并跳出循环。
  函数的最后就是关闭各类句柄的代码了:

if (!mygame.playagain()) {
			SetEvent(h_event2);
			ReleaseSemaphore(hSemaphore, 1, NULL);
			CloseHandle(hSemaphore);
			CloseHandle(hThread);
			CloseHandle(h_event1);
			CloseHandle(h_event2);
			break;
		}

至此,贪吃蛇网游化框架的主体搭建就全部完成了,整个框架还存在很多的不足,例如异常处理代码几乎全部被忽略,但出于只是复习所学知识的目的就不多做重复性工作了,下面贴几张游戏运行过程图:
  这里写图片描述
  这里写图片描述
  这里写图片描述
  这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值