Cocos2d-X多執行緒(3) cocos2dx中的執行緒安全
在使用多執行緒時,總會遇到執行緒安全的問題。cocos2dx 3.0系列中新加入了一個專門處理執行緒安全的函式performFunctionInCocosThread(),他是Scheduler類的一個成員函式:
void Scheduler::performFunctionInCocosThread(const std::function<void ()> &function)
當在其他執行緒中呼叫cocos2d的函式時使用該函式。
使用這個函式就能安全的在其他執行緒中去控制cocos2dx的一些操作了。比如在worker執行緒中對精靈的建立等操作可能會沒有用,在performFunctionInCocosThread就能很容易實現。
比如:
void thread_fun()
{
log("new thread create:t_id:0x%x",GetCurrentThreadId());
Director::getInstance()->getScheduler()->performFunctionInCocosThread([&,this]
{
for(int i=0;i<=1000;i++){}
log("[performFunctionInCocosThread] finished!");
});
log("thread finished:t_id:0x%x",GetCurrentThreadId());
}
這時會看到一個問題,執行緒結束後performFunctionInCocosThread中執行的程式碼才結束,這是因為使用performFunctionInCocosThread將引數函式中的程式碼放到主執行緒中去執行,所以就無法知道執行完這段程式碼需要多少時間。
有時還會遇到互斥問題,如果線上程中要使用互斥,而又要使用performFunctionInCocosThread。遇到這種情況將performFunctionInCocosThread呼叫放到執行緒的最後,然後在performFunctionInCocosThread呼叫函式的末尾使用mutex.unlock(),這樣才能確保互斥。
程式碼實操:
標頭檔案:
#ifndef __TestThreadSafe_SCENE_H__ #define __TestThreadSafe_SCENE_H__ #include "cocos2d.h" USING_NS_CC; class TestThreadSafe : public cocos2d::Layer { public: static cocos2d::Scene* createScene(); virtual bool init(); CREATE_FUNC(TestThreadSafe); void threadA(); }; #endif // __TestThreadSafe_SCENE_H__
原始檔:
#include "TestThreadSafe.h" #include <thread> Scene* TestThreadSafe::createScene() { auto scene = Scene::create(); auto layer = TestThreadSafe::create(); scene->addChild(layer); return scene; } bool TestThreadSafe::init() { if ( !Layer::init() ) { return false; } std::thread t1(&TestThreadSafe::threadA,this); t1.detach(); return true; } void TestThreadSafe::threadA() { Director::getInstance()->getScheduler()->performFunctionInCocosThread([&,this]{ auto sprite = Sprite::create("HelloWorld.png"); addChild(sprite); Size size = Director::getInstance()->getWinSize(); sprite->setPosition(size/2); }); }