网络游戏制作:网络游戏制作技术( 5)



  最近自己主持项目出现些问题太忙了所以好久都没有继续写东西和大家进行探讨制作开发部分了在这节中就要向大家介绍另外个重要部分并且也是最头疼部分:线程同步和数据保护

   有关线程概念我在前面章节中已经介绍过了也就在这里不累赘—“重复再重复”了定线程基础人都知道线程只要创建后就如同脱缰野马对于这样匹野马我们如何来进行控制和处理呢?简单我们没有办法进行控制我们更本就没有办法知道CPU什么时候来执行他们执行他们次序又是什么?

   有人要问没有办法控制那我们如何是好呢?这个问题也正是我这里要向大家进行解释和介绍说明虽然我们不能够控制他们运行但我们可以做些手脚来达到我们自己意志

   这里我们做手脚也就是对线程进行同步有关同步概念大家在操作系统中应该都看过吧!不了解我简单说说:读和写关系(我读书时候请你不要在书上乱写否则我就没有办法继续阅读了)

处理有两种:用户方式内核方式
用户方式线程同步由于有好几种:原子访问关键代码段

   在这里主要向大家介绍关键代码段处理(我个人用比较多简单实用)先介绍下它随后提供关键代码段处理类供大家参考(比较小我就直接贴上来了)

VOID InitializeCriticalSection( //化互斥体
LPCRITICAL_SECTION lpCriticalSection // critical section
);

VOID DeleteCriticalSection( //清除互斥体
LPCRITICAL_SECTION lpCriticalSection // critical section
);

VOID EnterCriticalSection( //进入等待
LPCRITICAL_SECTION lpCriticalSection // critical section
);

VOID LeaveCriticalSection( //释放离开
LPCRITICAL_SECTION lpCriticalSection // critical section
);

以上就是有关关键代码段基本API了介绍就不必了(MSDN)而我处理类只是将这几个进行了组织也就是让大家能够更加理解关键代码端

.h
CCriticalSection //共享变量区类
{
public:
CCriticalSection;
virtual ~CCriticalSection;
void Enter; //进入互斥体
void Leave; //离开互斥体释放资源
private:
CRITICAL_SECTION g_CritSect;
};

.cpp
CCriticalSection::CCriticalSection
{
InitializeCriticalSection(&g_CritSect);
}

CCriticalSection::~CCriticalSection
{
DeleteCriticalSection(&g_CritSect);
}

void CCriticalSection::Enter
{
EnterCriticalSection(&g_CritSect);
}

void CCriticalSection::Leave
{
LeaveCriticalSection(&g_CritSect);
}

由于篇幅有限关键代码段就说到这里接下来向大家简单介绍下内核方式下同步处理

   哎呀!这下可就惨了这可是要说好多哦!书上罗罗嗦嗦我就不说了我就说些我平时运用吧首先内核对象和我们使用对象是不这样些对象我们可以简单理解为特殊对象而我们内核方式同步就是利用这样些特殊对象进行处理我们同步其中包括:事件对象互斥对象信号量等对于这些内核对象我只向大家介绍说明两点:
1.内核对象创建和销毁
2.内核对象等待处理和等待副作用

:内核对象创建方式基本上而言都没有什么太大差别例如:创建事件就用HANDLE CreateEvent(…..),创建互斥对象 HANDLE CreateMutex(…….)而大家注意也是这 3个内核对象在创建过程中是有差异对于事件对象我们必须明确指明对象是人工对象还是自动对象而这种对象等待处理方式是完全区别什么区别下面说(呵呵)互斥对象比较简单没什么说信号量我们创建必须注意我们要定义最大使用数量和化量最大数量>化量再有如果我们为我们内核对象起名字我们就可以在整个进程中共用也可以被其他进程使用只需要OPEN就可以了也就不多说了

第 2:内核对象等待般情况下我们使用两个API:
DWORD WaitForSingleObject( //单个内核对象等待
HANDLE hHandle, // handle to object
DWORD dwMilliseconds // time-out erval
);

DWORD WaitForMultipleObjects( //多个内核对象等待
DWORD nCount, // number of handles in .gif' />
CONST HANDLE *lpHandles, // object-handle .gif' />
BOOL fWaitAll, // wait option
DWORD dwMilliseconds // time-out erval
);

具体如何用查MSDN了

   具体我们来说等待副作用主要说事件对象首先事件对象是分两种:人工自动人工等待是没有什么副作用(也就是说等待成功后要和其他对象样要进行手动释放)而自动就不但激发事件后返回后自动设置为未激发状态这样造成等待结果也不如果有多个线程在进行等待事件如果是人工事件被激活后所有等待线程成执行状态而自动事件只能有其中个线程可以返回继续执行所以说在使用这些内核对象时候要充分分析我们使用目再来设定我们创建时候简单同步我就说到这里了下面我就将将我们般情况下处理游戏服务器处理过程中数据保护问题分析:

首先向大家说说服务器方面数据保护重要性图例如下:

用户列表

     用户删除

     用户数据修改



     使用数据

加入队列

   对于上面图例大家应该也能够看出在我们游戏服务器的中我们要对于我们用户操作是多么频繁如此频繁操作我们如果不进行处理后果将是悲惨和可怕举例:如果我们在个线程删除用户瞬间有线程在使用那么我们将是不可难以预料我们将用到了数据可能会导致服务器崩溃再者我们多个线程在修改用户数据我们用户数据将是没有办法保持正确性等等情况都可能发生如何样杜绝这样些情况发生呢?我们就必须要进行服务器数据保护而我们如何正确保护好数据才能够保持服务器稳定运行呢?下面说些实际处理中些经验的谈

1.我们必须充分判断和估计我们服务器中有那些数据要进行数据保护这些就需要设计者和规划者要根据自己经验进行合理分析例如:在线用户信息列表在线用户数据信息消息列表等

2.正确和十分小心保护数据和正确分析要保护数据大家知道我们要在很多地方实现我们保护措施也就是说我们必须非常小心谨慎来书写我们保护不正确保护会造成系统死锁服务器将无法进行下去(我在处理过程中就曾经遇到过头都大了)正确分析要保护数据也就是说我们必须要估计到我们要保护部分处理能够比较快结束否则我们必须要想办法解决这个问题:例如:

DATA_STRUCT g_data;
CRITICAL_SECTION g_cs;

EnterCriticalSection(&g_cs);
SendMessage(hWnd,WM_ONEMSG,&g_data,0);
LeaveCriticalSection(&g_cs);

以上处理就有问题了我们不知道SendMessage()什么时候完成可能是1/1000豪秒也可能是1000年那我们其他线程也就不用活了所以我们必须改正这种情况

DATA_STRUCT g_data;
CRITICAL_SECTION g_cs;

EnterCriticalSection(&g_cs);
PostMessage(hWnd,WM_ONEMSG,&g_data,0);
LeaveCriticalSection(&g_cs);

或者 DATA_STRUCT temp_data;

EnterCriticalSection(&g_cs);
temp_data = g_cs;
LeaveCriticalSection(&g_cs);
SendMessage(hWnd,WM_ONEMSG,& temp_data,0);

3.最好不要复合保护用户数据这样可能会出现些潜在死锁

   简而言的服务器用户数据是定需要进行保护但我们在保护过程中就定需要万分小心和谨慎这篇我就说到这里了具体还是需要从实战中来进行学习下节想和大家讲讲服务器场景处理部分先做事去了呵呵!!有好想法和建议和我交流探讨先谢谢了

  本文配套档案

QQ : 81556019
MSG : [email protected]

Tags:  网络游戏制作软件 如何制作网络游戏 网络游戏外挂制作 网络游戏制作

延伸阅读

最新评论

发表评论