多线程在随着cpu发展应用的是越来越多,游戏场景因为其在服务器所占的数据量与逻辑复杂度的原因必须依赖于它。为什么场景要采用多线程?场景的线程是怎样的?场景的线程又是如何创建的?场景的线程又是怎样管理的?在这里同时对可以指正错误的朋友们说声谢谢,虽然是小错误,也希望大家能够勇于纠正这些错误。

游戏截图

采用理由

上面的两张截图分别在不同的场景,试想一下如果一个线程只能先处理其中一张图的数据,后果会怎么样?

单线程往往需要等待,就好像我们到银行窗口办理业务的时候,以前的时候很多网点只有一个窗口,所以我们不得不排队等候,然而随着时代的进步银行的窗口随着业务的开展越来越多,更多的业务员使得我们省去了排队的烦恼。而游戏场景在游戏中处理的逻辑是最为复杂的,特别是一些大场景的数据那更是多不胜数,程序处理逻辑数据需要时间,在单线程里面对复杂的逻辑就需要等待不少的时间,数据和逻辑越复杂其等待的时间就会越长,你想如果我们在玩游戏的时候在A场景的时候,B场景因为要等待A场景的逻辑处理完成后才能够处理其场景的数据,也就是说A场景的人先走动完成后,B场景的玩家才能走动。
  为了让所有场景的数据都能在较短的时间内处理,我们就需要更多的处理者来帮忙,也就是我们拥有更多的线程来处理,如果只有一个线程处理N个场景当然很慢,如果有M个场景同时处理N个场景速度则会大大提高,这就是我们之所以选择多线程的原因。而且一个线程所能承受的场景数量,往往是跟场景的数据量大小以及复杂度有关。

场景多线程

1、线程管理器(manager)

用于添加场景线程并初始化线程数据。

2、线程池(pool)

多个线程数据的集合管理。

3、线程分配(thread)

这个世界上最理想的是有足够的资源,就像这里一样每个线程负责一个场景就是最理想的,因为这样效率是最高的。线程越多消耗的CPU自然成正比例的增加,就好像地球上的资源一样,没有办法完全的满足需求一样,这样我们就必须想办法进行资源共享,一个线程负责多个场景。记得小时候的劳动课一样,有时候工具不够的情况下,老师往往会将同学们分成几组,每组共享那些工具,但是有的时候一个工具分了很多人使用,超过了负荷的时候就达不到老师的要求(比如老师要求规定时间内每个人都要使用工具多少次,因为人数太多甚至有的人工具都碰不到)。

线程的负载主要表现在程序执行的快慢和效率上,如果效率明显很低影响到了正常的工作,我们就不得不想办法提升效率。最直接影响场景线程的负载的便是负责场景数量,所以场景线程有规定的场景上限。

一般流程

场景管理器创建所有场景(scene manager)->线程池对象初始化(thread pool)->线程管理器分配场景线程(thread manager)->场景线程管理器运行所有线程(thread manager)

算法(交换排序)

1、冒泡排序(bubble sort)

交换相邻的两个元素,将最大的元素逐渐移动到最后,如果数组大小为N,则N次之后数组则变为有序的数组。泡排序算法主要用于排序元素较少且时间要求不太高的场合。这里进行了算法改进:增加一个标记,如果已经没有需要交换的元素则后面不需再排序。

code.

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h> /**
* 交换相邻的两个元素,将最大的元素逐渐移动到最后,如果数组大小为N,则N次之后数组则变为有序的数组
* 冒泡排序算法主要用于排序元素较少且时间要求不太高的场合
* 算法改进:增加一个标记,如果已经没有需要交换的元素则后面不需再排序
*/ void printarray(int32_t array[], int32_t length);
void bubblesort(int32_t array[], int32_t length); int32_t main(int32_t argc, char *argv[]) {
int32_t array[] = {, , , , , , , , , };
int32_t length = sizeof(array) / sizeof(array[]);
bubblesort(array, length);
return ;
} void printarray(int32_t array[], int32_t length) {
int32_t i;
for (i = ; i < length; ++i)
printf("%4d", array[i]);
printf("\n");
} void bubblesort(int32_t array[], int32_t length) {
int32_t i, j;
int32_t temp;
uint8_t flag = ;
for (i = ; i < length && == flag; ++i) {
flag = ;
for (j = ; j < length - i; ++j) {
if (array[j] > array[j + ]) {
temp = array[j];
array[j] = array[j + ];
array[j + ] = temp;
flag = ;
}
}
printf("the %d times result: ", i);
printarray(array, length);
}
}

result.

2、快速排序(quick sort)

快速排序算法是冒泡排序算法的改进,但是实现却比冒泡复杂很多,它主要针对大数据排序,果对时间要求不是很高可以使用直接插入排序或者冒泡排序。其特点是排序的时间效率比较高,并且在特别大的数据量时十分明显。同希尔算法一样,快速排序是一种不太稳定的算法,和其实现的原理有关。

code.

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h> /**
* 快速排序算法是冒泡排序算法的改进,但是实现却比冒泡复杂很多,它主要针对大数据排序,
* 如果对时间要求不是很高可以使用直接插入排序或者冒泡排序
* 其特点是排序的时间效率比较高,并且在特别大的数据量时十分明显。
* 同希尔算法一样,快速排序是一种不太稳定的算法,和其实现的原理有关。
*/ //数组打印
void displayarray(int32_t array[], int32_t length);
//输出每次划分的结果
void _displayarray(int32_t array[], int32_t length, int32_t pivot, int32_t count);
//快速排序核心实现
void _quicksort(int32_t array[], int32_t length, int32_t low, int32_t high);
//快速排序函数,对数组的元素进行排序
void quicksort(int32_t array[], int32_t length);
//对素组array[low...high]的元素进行一趟排序,使枢轴前面的元素小于枢轴元素,
//枢轴后面的元素大于等于枢轴元素,并返回枢轴元素
int32_t partition(int32_t array[], int32_t low, int32_t high); int32_t main(int32_t argc, char *argv[]) {
int32_t array[] = {, , , , , , , , , , };
int32_t length = sizeof(array) / sizeof(array[]);
printf("before sort: ");
displayarray(array, length);
quicksort(array, length);
printf("after sort: ");
displayarray(array, length);
return ;
} void displayarray(int32_t array[], int32_t length) {
int32_t i;
for (i = ; i < length; ++i)
printf("%4d", array[i]);
printf("\n");
} void _displayarray(int32_t array[],
int32_t length,
int32_t pivot,
int32_t count) {
int32_t i;
printf("the %d times result: [", count);
for (i = ; i < pivot; ++i)
printf("%-4d", array[i]);
printf("]");
printf("%3d ", array[pivot]);
printf("[");
for (i = pivot + ; i < length; ++i)
printf("%-4d", array[i]);
printf("]");
printf("\n");
} void _quicksort(int32_t array[], int32_t length, int32_t low, int32_t high) {
int32_t pivot;
static int32_t count = ;
if (low < high) { //如果元素序列的长度大于1
pivot = partition(array, low, high); //将待排序序列array[low...high]划分为两部分
_displayarray(array, length, pivot, count); //输出每次划分的结果
++count;
_quicksort(array, length, low, pivot - ); //对左边的子表进行递归排序,pivot是枢轴位置
_quicksort(array, length, pivot + , high); //对右边的子表进行递归排序
}
} void quicksort(int32_t array[], int32_t length) {
_quicksort(array, length, , length - );
} int32_t partition(int32_t array[], int32_t low, int32_t high) {
int32_t temp, pivot;
pivot = array[low]; //将第一个元素作为枢轴元素
temp = array[low];
while (low < high) { //从表的两端交替的向中间扫描
while (low < high && array[high] >= pivot) //从表的末端向前扫描
--high;
if (low < high) { //将当前high指向的元素保存在low位置
array[low] = array[high];
++low;
}
while (low < high && array[low] <= pivot) //从表的开始向后扫描
++low;
if (low < high) { //将当前low指向的元素保存在high位置
array[high] = array[low];
--high;
}
array[low] = temp;
}
return low;
}

result.

MMORPG大型游戏设计与开发(服务器 游戏场景 多线程)的更多相关文章

  1. MMORPG大型游戏设计与开发(游戏服务器 游戏场景 概述 updated)

    我们在玩游戏的时候,我们进入游戏后第一眼往往都是看到游戏世界中的场景,当然除了个别例外,因为那些游戏将游戏场景隐藏了起来,如文字游戏中的地点一样.既然我们接触了游戏世界的核心,那么作为核心的场景又包括 ...

  2. MMORPG大型游戏设计与开发(服务器 AI 概述)

    游戏世界中我们拥有许多对象,常见的就是角色自身以及怪物和NPC,我们可以见到怪物和NPC拥有许多的行为,比如说怪物常常见到敌对的玩家就会攻击一样,又如一些NPC来游戏世界中走来走去,又有些怪物和NPC ...

  3. MMORPG大型游戏设计与开发(服务器 游戏场景 动态场景与副本)

    场景的内容讲解到今天算是暂时划上一个句号了,接下来为大家讲解的是AI部分(大型AI),如果有兴趣的朋友不妨持续关注这些文章,大家一起学习和进步.动态场景和副本是场景中特殊的类型,副本在这里想必已经是无 ...

  4. MMORPG大型游戏设计与开发(概述)updated

    1.定义 MMORPG,是英文Massive(或Massively)Multiplayer Online Role-PlayingGame的缩写,即大型多人在线角色扮演游戏. 2.技术与知识 在这系列 ...

  5. MMORPG大型游戏设计与开发(客户端架构 part8 of vegine)

    脚本模块是游戏设计中争论比较多的话题,那是因为作为脚本本身所带来的利弊.其实这都无关紧要,取舍是人必须学会的一项技能,如果你不会取舍那么就让趋势给你一个满意的答复.自从魔兽世界以及传奇(世界)问世以来 ...

  6. MMORPG大型游戏设计与开发(服务器 游戏场景 地图和区域)

    地图的数据以及区域的信息是场景的重要组成部分,这些数据同时存在客户端和服务器,而且都是由编辑器生成的.那么保存的文件数据结构是怎样的?一张3D的场景地图又是怎样处理这些数据的?同时告诉大家这里同样只是 ...

  7. MMORPG大型游戏设计与开发(服务器 游戏场景 核心详述)

    核心这个词来的是多么的高深,可能我们也因为这个字眼望而却步,也就很难去掌握这部分的知识.之所以将核心放在最前面讲解,也可以看出它真的很重要,希望朋友们不会错过这个一直以来让大家不熟悉的知识,同我一起进 ...

  8. MMORPG大型游戏设计与开发(服务器 AI 事件)

    AI中的事件与场景中的事件大致相同,都是由特定的条件触发的.只不过AI的事件与其他事件不同的是,对于AI的事件往往是根据不同的AI类型,和动态的触发条件下才产生的.其实不管AI多么智能,它对应的触发条 ...

  9. MMORPG大型游戏设计与开发(服务器 AI 基础接口)

    一个模块都往往需要统一的接口支持,特别是对于非常大型的模块,基础结构的统一性非常重要,它往往决定了其扩展对象的通用性.昨天说了AI的基本概述以及组成,作为与场景模块中核心一样重要的地位,基础部分的设计 ...

随机推荐

  1. Suggestion(搜索建议)产品和技术

    今天来简单聊聊Suggestion产品 什么是Suggestion服务? 一图胜千言: 当你想要搜索某个长词语或者一句话输入部分时,Suggestion服务预测你极大可能的候选项,并罗列出来,供你选择 ...

  2. Java并发编程:线程池的使用

    Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...

  3. spi 10方式编写

    //第一个CS变低的时候要sclk为高电平,第一个跳变沿进行赋值 module spi(input clk,input rst_n,output reg sclk,output reg cs,outp ...

  4. 从零开始学Python第七周:面向对象进阶(需修改)

    一,类的属性 (1)示例 通过属性获取已经创建对象的个数 class Plane: pCount = 0 #类属性 def __init__(self,name,category): self.nam ...

  5. JAVA 链表操作:单链表和双链表

    主要讲述几点: 一.链表的简介 二.链表实现原理和必要性 三.单链表示例 四.双链表示例 一.链表的简介 链表是一种比较常用的数据结构,链表虽然保存比较复杂,但是在查询时候比较便捷,在多种计算机语言都 ...

  6. error C2664: 'BOOL (PCERT_SELECT_STRUCT_A)' : cannot convert parameter 1 from 'CERT_SELECT_STRUCT *' to 'PCERT_SELECT_STRUCT_A'

    1. 编译c++程序出现标题所示错误 2. 解决方法:更改编码设置

  7. SSH整合之全注解

    SSH整合之全注解 使用注解配置,需要我们额外引入以下jar包

  8. JavaWeb之CSS详解

    CSS的简介 1.CSS概述及作用 CSS:Cascading Style Sheets)是层叠样式表用来定义网页的显示效果.可以解决html代码对样式定义的重复,提高了后期样式代码的可维护性,并增强 ...

  9. 字符编码笔记:ASCII,Unicode和UTF-8

    很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物.他们看到8个开关状态是好的,于是他们把这称为"字节". 再后来,他们又做了一些可以处理 ...

  10. HTTP 协议整理(转)

    HTTP 协议 作为web开发人员,了解一些http协议的知识很有必要.本文简单介绍了HTTP协议的知识,若有错误的地方,望大家斧正. 1.HTTP协议是什么? http协议是一个应用层的协议.规定了 ...