时隔这么久 才再一次的回归正题继续讲解游戏服务器开发。开始讲解前有一个问题需要修正。之前讲的线程和定时器线程的时候是分开的。但是真正地图线程与之前的线程模型是有区别的。 为什么会有区别呢?一个地图肯定有执行线程,但是每一个地图都有不同的时间任务。比如检测玩家身上的buffer ...
时隔这么久 才再一次的回归正题继续讲解游戏服务器开发。
开始讲解前有一个问题需要修正。之前讲的get='_blank'>线程和定时器线程的时候是分开的。
但是真正地图线程与之前的线程模型是有区别的。
为什么会有区别呢?一个地图肯定有执行线程,但是每一个地图都有不同的时间任务。
我的处理方式是创建一个线程的时候根据需求创建对应的 timerthread
直接上代码其他不BB
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading; 6 using System.Threading.Tasks; 7 8 namespace Sz.ThreadPool 9 { 10 /// <summary> 11 /// 线程模型 12 /// </summary> 13 public class ThreadModel 14 { 15 /// <summary> 16 /// 17 /// </summary> 18 public bool IsStop = false; 19 /// <summary> 20 /// ID 21 /// </summary> 22 public int ID { get; private set; } 23 /// <summary> 24 /// 已分配的自定义线程静态ID 25 /// </summary> 26 public static int StaticID { get; private set; } 27 28 string Name; 29 30 /// <summary> 31 /// 初始化线程模型, 32 /// </summary> 33 /// <param name="name"></param> 34 public ThreadModel(String name) 35 : this(name, 1) 36 { 37 38 } 39 40 /// <summary> 41 /// 初始化线程模型 42 /// </summary> 43 /// <param name="name">线程名称</param> 44 /// <param name="count">线程数量</param> 45 public ThreadModel(String name, Int32 count) 46 { 47 lock (typeof(ThreadModel)) 48 { 49 StaticID++; 50 ID = StaticID; 51 } 52 this.Name = name; 53 if (count == 1) 54 { 55 System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(Run)); 56 thread.Name = "< " + name + "线程 >"; 57 thread.Start(); 58 Logger.Info("初始化 " + thread.Name); 59 } 60 else 61 { 62 for (int i = 0; i < count; i++) 63 { 64 System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(Run)); 65 thread.Name = "< " + name + "_" + (i + 1) + "线程 >"; 66 thread.Start(); 67 Logger.Info("初始化 " + thread.Name); 68 } 69 } 70 } 71 72 System.Threading.Thread threadTimer = null; 73 74 /// <summary> 75 /// 任务队列 76 /// </summary> 77 protected List<TaskModel> taskQueue = new List<TaskModel>(); 78 /// <summary> 79 /// 任务队列 80 /// </summary> 81 private List<TimerTask> timerTaskQueue = new List<TimerTask>(); 82 83 /// <summary> 84 /// 加入任务 85 /// </summary> 86 /// <param name="t"></param> 87 public virtual void AddTask(TaskModel t) 88 { 89 lock (taskQueue) 90 { 91 taskQueue.Add(t); 92 } 93 //防止线程正在阻塞时添加进入了新任务 94 are.Set(); 95 } 96 97 /// <summary> 98 /// 加入任务 99 /// </summary>100 /// <param name="t"></param>101 public void AddTimerTask(TimerTask t)102 {103 t.RunAttribute["lastactiontime"] = SzExtensions.CurrentTimeMillis();104 if (t.IsStartAction)105 {106 AddTask(t);107 }108 lock (timerTaskQueue)109 {110 if (threadTimer == null)111 {112 threadTimer = new System.Threading.Thread(new System.Threading.ThreadStart(TimerRun));113 threadTimer.Name = "< " + this.Name + " - Timer线程 >"; 114 threadTimer.Start();115 Logger.Info("初始化 " + threadTimer.Name);116 }117 timerTaskQueue.Add(t);118 }119 timerAre.Set();120 }121 122 /// <summary>123 /// 通知一个或多个正在等待的线程已发生事件124 /// </summary>125 protected ManualResetEvent are = new ManualResetEvent(false);126 127 /// <summary>128 /// 通知一个或多个正在等待的线程已发生事件129 /// </summary>130 protected ManualResetEvent timerAre = new ManualResetEvent(true);131 132 /// <summary>133 /// 线程处理器134 /// </summary>135 protected virtual void Run()136 {137 while (!this.IsStop)138 {139 while ((taskQueue.Count > 0))140 {141 TaskModel task = null;142 lock (taskQueue)143 {144 if (taskQueue.Count > 0)145 {146 task = taskQueue[0];147 taskQueue.RemoveAt(0);148 }149 else { break; }150 }151 152 /* 执行任务 */153 //r.setSubmitTimeL();154 long submitTime = SzExtensions.CurrentTimeMillis();155 try156 {157 task.Run();158 }159 catch (Exception e)160 {161 Logger.Error(Thread.CurrentThread.Name + " 执行任务:" + task.ToString() + " 遇到错误", e);162 continue;163 }164 long timeL1 = SzExtensions.CurrentTimeMillis() - submitTime;165 long timeL2 = SzExtensions.CurrentTimeMillis() - task.GetSubmitTime();166 if (timeL1 < 100) { }167 else if (timeL1 <= 200L) { Logger.Debug(Thread.CurrentThread.Name + " 完成了任务:" + task.ToString() + " 执行耗时:" + timeL1 + " 提交耗时:" + timeL2); }168 else if (timeL1 <= 1000L) { Logger.Info(Thread.CurrentThread.Name + " 长时间执行 完成任务:" + task.ToString() + " “考虑”任务脚本逻辑 耗时:" + timeL1 + " 提交耗时:" + timeL2); }169 else if (timeL1 <= 4000L) { Logger.Error(Thread.CurrentThread.Name + " 超长时间执行完成 任务:" + task.ToString() + " “检查”任务脚本逻辑 耗时:" + timeL1 + " 提交耗时:" + timeL2); }170 else171 {172 Logger.Error(Thread.CurrentThread.Name + " 超长时间执行完成 任务:" + task.ToString() + " “考虑是否应该删除”任务脚本 耗时:" + timeL1 + " 提交耗时:" + timeL2);173 }174 task = null;175 }176 are.Reset();177 //队列为空等待200毫秒继续178 are.WaitOne(200);179 }180 Console.WriteLine(DateTime.Now.NowString() + " " + Thread.CurrentThread.Name + " Destroying");181 }182 183 /// <summary>184 /// 定时器线程处理器185 /// </summary>186 protected virtual void TimerRun()187 {188 ///无限循环执行函数器189 while (!this.IsStop)190 {191 if (timerTaskQueue.Count > 0)192 {193 IEnumerable<TimerTask> collections = null;194 lock (timerTaskQueue)195 {196 collections = new List<TimerTask>(timerTaskQueue);197 }198 foreach (TimerTask timerEvent in collections)199 {200 int execCount = timerEvent.RunAttribute.GetintValue("Execcount");201 long lastTime = timerEvent.RunAttribute.GetlongValue("LastExecTime");202 long nowTime = SzExtensions.CurrentTimeMillis();203 if (nowTime > timerEvent.StartTime //是否满足开始时间204 && (nowTime - timerEvent.GetSubmitTime() > timerEvent.IntervalTime)//提交以后是否满足了间隔时间205 && (timerEvent.EndTime <= 0 || nowTime < timerEvent.EndTime) //判断结束时间206 && (nowTime - lastTime >= timerEvent.IntervalTime))//判断上次执行到目前是否满足间隔时间207 {208 //提交执行209 this.AddTask(timerEvent);210 //记录211 execCount++;212 timerEvent.RunAttribute["Execcount"] = execCount;213 timerEvent.RunAttribute["LastExecTime"] = nowTime;214 }215 nowTime = SzExtensions.CurrentTimeMillis();216 //判断删除条件217 if ((timerEvent.EndTime > 0 && nowTime < timerEvent.EndTime)218 || (timerEvent.ActionCount > 0 && timerEvent.ActionCount <= execCount))219 {220 timerTaskQueue.Remove(timerEvent);221 }222 }223 timerAre.Reset();224 timerAre.WaitOne(5);225 }226 else227 {228 timerAre.Reset();229 //队列为空等待200毫秒继续230 timerAre.WaitOne(200);231 }232 }233 Console.WriteLine(DateTime.Now.NowString() + "Thread:<" + Thread.CurrentThread.Name + "> Destroying");234 }235 }236 }
海外公司注册、海外银行开户、跨境平台代入驻、VAT、EPR等知识和在线办理:https://www.xlkjsw.com
原标题:一步一步开发Game服务器(四)地图线程
关键词:线程
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:
admin#shaoqun.com
(#换成@)。