利用无锁多线程实现游戏资源的加载

www.joy70.com

 

出于资源加载效率方面的考虑,我们使用无锁多线程来实现这一模块。

 

类型设计:

1.       任务信息:

struct TaskInfo

{

       T task;                //任务标识

       TaskType  taskType;    //任务类型, LOAD/FREE/NONE(主线程可写,子线程只读)

       TaskState  taskState;   //任务当前状态, NA/TODO/DONE(主线程可写,子线程只读)

       unsigned int  uiPriority; //任务优先级,(主线程可写,子线程只读)

       unsigned int  uiPushbackTimes; //任务被搁置的次数,(主线程可写,子线程只读)

       void* handle;          //资源地址,(主线程只读,子线程可写)

       unsigned long ulSize;    //资源长度,(主线程只读,子线程可写)

};

2.       任务队列:

class TaskQueue

{

        //仅供主线程访问

        //TaskQueue中,为所资源建立索引

        void Initialize(); 

 

        //仅供主线程访问

        //TaskQueue中任务数不变,仅仅将资源对应的任务类型改为LOAD/FREE,任务状态//改为TODO

        void AddTask(); 

 

        //仅供主线程访问

        //仅将资源对应的任务类型改为NONE

        void RemoveTask(); 

 

        //仅供子线程访问

        //从任务队列中找到最需要执行的一个任务,由任务调度算法决定

        TaskInfo GetTask();

 

        //仅供子线程访问

        //任务完成后,将资源地址传给任务的handle,大小传给任务的ulSize

        void TaskDone();

};

 

加载流程:

1.       初始化任务队列TaskQueue,为每个资源定义一个TaskInfo 对象加入队列,置初始状态。

2.       当有资源需要加载/释放时,主线程调用AddTask()改变该资源对应的TaskInfo的状态

3.       子线程循环调用GetTask(),从TaskQueue中取得要执行的任务,若有,则执行之。

4.       子线程执行完任务,调用TaskDone()将资源地址和长度保存;若为释放任务,则将资源地址置NULL,长度置0.

 

说明:

1.       任务队列长度固定,所以避免了插入/删除造成的主/子线程信息的不一致。

2.       对于同一变量,主线程和子线程只有一方具有可写权,从而避免信息冲突。

3.       主线程和子线程,一方读,另一方写,这种情况下,信息的不一致可通过程序逻辑加以避免。

 

 

本文代码片段均为伪代码,不可直接使用。

由于作者水平有限,不足之处,还望大家批评指正!

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值