大佬教程收集整理的这篇文章主要介绍了cocos2dx多线程以及线程同步 与 cocos2dx内存管理与多线程问题,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_696_2@
cocos2d-x引擎在内部实现了一个庞大的主循环,每帧之间更新界面,如果耗时的操作放到了主线程中,游戏的界面就会卡,这是不能容忍的,游戏最基本的条件就是流畅性,这就是为什么游戏开发选择C++的原因。另外现在双核手机和四核手机越来越普遍了,是时候使用多线程来挖掘硬件的潜力了。@H_696_2@
cocos2d-x中的多线程使用pthread就可以实现跨平台,而且也不是很难理解。使用pthread需要先配置一下工程。右击工程----->属性----->配置属性---->链接器----->输入---->附加依赖项中添加pthreadVCE2.lib,如下图@H_696_2@
@H_696_2@
接着添加附加包含目录,右击项目,属性----->C/C++---->常规----->附加包含目录加入pthread头文件所在的目录@H_696_2@
@H_696_2@
这样,环境就搭建起来了。@H_696_2@
使用pthread来实现多线程,最重要的一个函数是@H_696_2@
然后自定义了一个类,用于给线程传递数据。student类如下:@H_696_2@
这里使用pthread_mutex_t来实现同步,下面我来演示一下使用多线程实现卖票系统。卖票的时候,是由多个窗口同时卖票,这里要做到一张票不要卖出去两次,不要出现有票却无法卖的结果。@H_696_2@
在线程函数th_run和th_go中来卖票,票的数量是一个全局变量,每卖出去一张票,就将票的数量减一。其中同步的pthread_mutex_t也是一个全局变量,就用它来实现线程同步。@H_696_2@
@H_755_34@mutex被锁定后,其他线程若再想锁定mutex的话,必须等待,当该线程释放了mutex之后,其他线程才能锁定mutex。Sleep()函数可以使得该线程休眠,单位是毫秒。下面是卖票的结果:@H_696_2@
可以看到,这个打印结果正确无误。如果不加mutex会是什么样的结果呢,我将线程同步的mutex注释掉,输出的结果为:@H_696_2@
可以看到,有的票卖了两次,有的票就没卖。@H_696_2@
1.Sleep()函数是使得线程休眠的函数,这个函数不跨平台,仅仅在windows上能用,其他平台使用usleep。@H_696_2@
2.在非主线程中不能使用COcos2d-x管理内存的CCObject::retain()
,@H_696_2@CCObject::release()
者@H_696_2@CCObject::autorelease(),因为CCAutoreleasePool不是线程安全的,OPENGL的上下文也不是线程安全的,所以不要再非主线程中使用COcos2d-x的API和UI操作。@H_696_2@
@H_696_2@@H_696_2@
cocos2dx内存管理与多线程问题:
@H_696_2@@H_696_2@
@H_696_2@
Cocos2d-x的内存管理采用Objective-C的机制,大喜过望。因为只要坚持Objective-C的原则“谁创建谁释放,谁备份谁释放”的原则即可确保内存使用不易出现Bug。@H_696_2@
@H_696_2@@H_696_2@
@H_829_2620@但是因为本身开放的游戏需要使用到多线程技术,导致测试的时候总是莫名其妙的导致空指针错误。而且是随机出现,纠结了2天无果后,开始怀疑Cocos2d-X的内存本身管理可能存在问题。怀着这样的想法,@H_696_2@@H_18_2622@一步一步的调试,发现经常出现指针异常的变量总是在调用autorelease后一会就莫名其妙再使用的时候就抛异常。狠下心,在它的析构函数里面断点+Log输出信息。发现对象被释放了。一时也很迷糊,因为对象只是@H_696_2@@H_18_2622@autorelease,并没有真正释放,是谁导致它释放的?@H_696_2@
@H_18_2622@然后就去看了CCAutoreleasePool的源码,发现存在Cocos2d-X的内存管理在多线程的情况下存在如下问题@H_696_2@@H_18_2622@ @H_829_2620@如图:thread 1和thread 2是独立的两个线程,它们之间存在CPU分配的交叉集,我们在time 1的时候push一个autorelease的自动释放池,在该线程的末尾,即time 3的时候pop它。同理在thread 2的线程里面,在time 2的时候push一个自动释放池,在time 4的时候释放它,即Pop.@H_696_2@@H_18_2622@此时我们假设在thread 2分配得到CPU的时候有一个对象obj自动释放,即obj-autorelease().@H_696_2@那么在time 3的时候会发生是么事情呢?@H_696_2@
答案很简单,就是obj在time 3的时候就被释放了,而我们期望它在time 4的时候才释放。所以就导致我上面说的,在多线程下面,cocos2d-x的autorelease变量会发生莫名其妙的指针异常。@H_696_2@
解决办法:@H_696_2@@H_829_2620@在PoolManager给每个线程根据pthread_t的线程id生成一个CCArray的stack的嵌套管理自动释放池。源码如下@H_696_2@@H_18_2622@所以我在Push的时候根据当前线程的pthread_t的线程id生成一个CCArray的stack来存储该线程对应的Autoreleasepool的嵌套对象@H_696_2@@H_18_2622@源码如下@H_696_2@
@H_829_2620@ @H_696_2@@H_696_2@
以上是大佬教程为你收集整理的cocos2dx多线程以及线程同步 与 cocos2dx内存管理与多线程问题全部内容,希望文章能够帮你解决cocos2dx多线程以及线程同步 与 cocos2dx内存管理与多线程问题所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。