首页 > Personal > cocos2d-x > cocos2d-x: 多线程
2014
01-09

cocos2d-x: 多线程

昨天想写一个异步下载url图片的功能,发现cocos2d-x本身没有自带的多线程功能,只能自己实现一个。

windows下的话可以使用cocos2d-x里面带的pthread库,在include目录里加入$(ProjectDir)..\..\..\cocos2dx\platform\third_party\win32\pthread,包含头文件#include “pthread.h”。其他系统下只要包含头文件就可以了,这是unix系统自带的库。

先使用pthread mutex实现一个Lock类用来做线程锁,再用pthread cond实现一个condition类用来做线程同步。最后就是主要的线程类Thread了。
线程间最主要的就是消息传递,我写了一个lockfree的队列来做每个线程消息队列,同时可以一个线程读,一个线程写,可以满足基本的需求了。其他线程使用send把消息发到消息队列,工作线程使用recv读取消息执行就可以了。消息的话我使用了自己写的Delegate,之前的文章有提到过,内部使用了std的function。这个类的指针通过pthread_setspecific绑定到线程上,函数currentThread通过pthread_getspecific来取得这个线程类的指针。主线程的话,在静态变量的构造析构函数中来创建销毁。

大概的实现就是这样,主要是遇到的问题,
先来说说cocos2d-x里面的object管理,多线程中retain和release虽然不是多线程的,但是只要可以保证只有一个线程调到,是可以使用的,但是autorelease是绝对不能使用的,因为autorelease是在主线程处理的,而且不能确定处理时间,只要用在多线程里很容易就出问题,所以绝对不能使用。我中间遇到的一个crash就是这么引起的,而且不是外面是用的问题,而是线程里使用的一个类里面有autorelease的对象出现的问题,所以说使用的时候一定要谨慎。
在android下面,currentThread取不到主线程的线程指针,怎么取都是空,还不确定是什么原因,目前用mainThread来代替就可以了。CCFileUtils::sharedFileUtils()->getWritablePath()只要不在主线程下调用取到的路径就是空,暂时也只能在主线程调用再传到其他线程里去。

这两天把自己写的类的基类全部换掉了,cocos2d-x的object多线程问题实在太多,换成了自己写的SharedObject,继承自 std::enable_shared_from_this,所有的内存管理使用std的shared_ptr,至少能够保证线程安全,用起来也很容易.

这两天,开始把工程移到wp8上,发现pthread这个库没有支持,wp8上多线程看了下网上都推荐用std的标准库,没办法,只能再把多线程改成std的。
mutex使用头文件#include ,用里面的std::mutex,用法相当简单。cond的话头文件#include ,可以使用std::condition_variable_any,以std::mutex为参数,std::condition_variable的话要是用std::unique_lock做参数。thread头文件#include ,使用std::thread和std::this_thread来实现。用法网上有一堆。需要注意的是android要编译过的话,需要一些修改,
jni/Application.mk添加
NDK_TOOLCHAIN_VERSION := 4.8 // 因为我用的ndk r9b所以版本是4.8,可能低版本的需要4.7。
jni/Android.mk修改
LOCAL_CPPFLAGS += -std=c++11 // 之前使用的是gun++0x

最后编辑:
作者:wy182000
这个作者貌似有点懒,什么都没有留下。

留下一个回复