源自於Objective-C的Ref對象,需要使用AutoreleasePool進行內存管理,AutoreleasePool是非線程安全的,所有不推薦在子多線程中調用Ref對象的retain()、 release()和autorelease()等函數。另外,OpenGL上下文對象也是不支持線程安全的。php
但是有的時候咱們需要異步載入一些資源,好比:載入圖片紋理、聲音的預處理和網絡請求數據等。html
假設是異步載入圖片紋理咱們可以使用第20.4.4一節介紹的內容。但聲音的預處理和網絡請求數據等就需要本身經過多線程技術實現了。
Cocos2d-x引擎也提供了多線程技術。Cocos2d-x 3.x以前是使用第三方的pthread技術。ios
Cocos2d-x 3.x以後使用C++11新規範中的std::thread多線程技術,std::thread使用起來比較簡單。
1.std::thread多線程技術
std::thread是C++11 引入了一個新的線程庫。它提供了線程管理相關函數。std::thread庫中還提供了std::mutex(相互排斥量)。經過std::mutex可以實現線程同步。
啓動一個新的線程很是easy。當咱們建立一個 std::thread 對象時候,它便會自行啓動。建立線程std::thread 對象時。可以提供該線程的回調函數。如下代碼實現了建立線程和線程函數的回調:
安全
#include <thread> #include <iostream> void callfn(){ ① std::cout << "Hello thread! " << std::endl; } int main(){ std::thread t1(callfn); ② t1.join(); ③ return 0; }
代碼第①行是回調函數的定義。第③行代碼t1.join()是將子線程與主線程合併,這樣的合併可以使子線程運行完畢後才幹繼續運行主線程,這是爲了不子線程還在運行,主線程已經運行結束而撤銷。微信
建立線程還可以使用堆的方式分配內存,代碼例如如下:
網絡
void callfn(){ std::cout << "Hello thread! " << std::endl; } int main(){ std::thread* t1 = new std::thread(callfn); ① t1->join(); delete t1; ② t1 = nullptr; ③ return 0; }
如下咱們介紹一下異步預處理聲音。多線程
咱們在前面20.5一節介紹了聲音預處理和清除,在那一節中預處理聲音是同步的。它會致使阻塞主線程,使用戶的感受會「卡」了一下。假設這個「卡」比較長。咱們解決主線程阻塞問題。改善用戶體驗,咱們可以異步預處理聲音。
咱們在20.5一節的案例中採用std::thread線程異步預處理聲音,咱們可以在AppDelegate中進行異步載入,改動以後的AppDelegate.h代碼例如如下:
#include "cocos2d.h"
#include "SimpleAudioEngine.h"
using namespace CocosDenshion;
class AppDelegate : private cocos2d::Application
{
private:
std::thread *_loadingAudioThread; ①
void loadingAudio(); ②
public:
AppDelegate();
virtual ~AppDelegate();
… …
};
咱們在第①行聲明瞭私有的std::thread線程指針變量_loadingAudioThread。第②代碼是聲明瞭私有的異步預處理聲音函數loadingAudio()。
改動以後的AppDelegate.cpp代碼例如如下:
併發
include "AppDelegate.h" #include "HelloWorldScene.h" USING_NS_CC; AppDelegate::AppDelegate() { _loadingAudioThread = new std::thread(&AppDelegate::loadingAudio,this); ① } AppDelegate::~AppDelegate() { _loadingAudioThread->join(); ② CC_SAFE_DELETE(_loadingAudioThread); ③ } bool AppDelegate::applicationDidFinishLaunching() { … … return true; } void AppDelegate::applicationDidEnterBackground() { Director::getInstance()->stopAnimation(); SimpleAudioEngine::getInstance()->pauseBackgroundMusic(); } void AppDelegate::applicationWillEnterForeground() { Director::getInstance()->startAnimation(); SimpleAudioEngine::getInstance()->resumeBackgroundMusic(); } void AppDelegate::loadingAudio() ④ { //初始化 音樂 SimpleAudioEngine::getInstance()->preloadBackgroundMusic("sound/Jazz.mp3"); SimpleAudioEngine::getInstance()->preloadBackgroundMusic("sound/Synth.mp3"); //初始化 音效 SimpleAudioEngine::getInstance()->preloadEffect("sound/Blip.wav"); }
第④行代碼AppDelegate::loadingAudio() 定義了線程回調函數。咱們在這個函數中預處理聲音。app
《Cocos2d-x實戰 C++卷》現已上線。各大商店均已開售:異步
京東:http://item.jd.com/11584534.html
亞馬遜:http://www.amazon.cn/Cocos2d-x%E5%AE%9E%E6%88%98-C-%E5%8D%B7-%E5%85%B3%E4%B8%9C%E5%8D%87/dp/B00PTYWTLU
噹噹:http://product.dangdang.com/23606265.html
互動出版網:http://product.china-pub.com/3770734
《Cocos2d-x實戰 C++卷》源代碼及樣章下載地址:
源代碼下載地址:http://51work6.com/forum.php?mod=viewthread&tid=1155&extra=page%3D1
樣章下載地址:http://51work6.com/forum.php?
mod=viewthread&tid=1157&extra=page%3D1