Cocos2d-x最佳化中多線程並發訪問,cocos2d-x多線程

來源:互聯網
上載者:User

Cocos2d-x最佳化中多線程並發訪問,cocos2d-x多線程
多線程並發訪問在Cocos2d-x引擎中用的不是很多,這主要是因為中整個結構設計沒有採用多線程。源自於Objective-C的Ref對象,需要使用AutoreleasePool進行記憶體管理,AutoreleasePool是非安全執行緒的,所有不推薦在子多線程中調用Ref對象的retain()、 release()和autorelease()等函數。另外,OpenGL內容物件也是不支援安全執行緒的。
但是有的時候我們需要非同步載入一些資源,例如:載入圖片紋理、聲音的預先處理和網路請求資料等。如果是非同步載入圖片紋理我們可以使用第20.4.4一節介紹的內容。但聲音的預先處理和網路請求資料等就需要自己通過多線程技術實現了。
Cocos2d-x引擎也提供了多線程技術,Cocos2d-x 3.x之前是使用第三方的pthread技術。Cocos2d-x 3.x之後使用C++11新規範中的std::thread多線程技術,std::thread使用起來比較簡單。


1.std::thread多線程技術
std::thread是C++11 引入了一個新的線程庫,它提供了線程管理相關函數,std::thread庫中還提供了std::mutex(互斥量),通過std::mutex可以實現線程同步。
啟動一個新的線程非常簡單,當我們建立一個 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線程對象,它的參數是函數指標callfn,如果需要,我們還可以為回呼函數提供參數。代碼第①行是回呼函數的定義。第③行代碼t1.join()是將子線程與主線程合并,這種合并能夠使子線程執行完成後才能繼續執行主線程,這是為了避免子線程還在執行,主線程已經執行結束而撤銷。
建立線程還可以使用堆的方式分配記憶體,代碼如下: 
void callfn(){    std::cout << "Hello thread! " << std::endl;}int main(){    std::thread* t1 = new  std::thread(callfn);①t1->join();deletet1;②t1 = nullptr;③    return 0;}


上述代碼第①行是通過堆方式分配記憶體,即通過new運算子建立動態線程對象。因此需要在使用完成的情況下釋放對象,我們在代碼第②行使用deletet1語句釋放,釋放完成還以通過代碼第③行t1 = nullptr設定指標變數,這樣可以防止“野指標”。


2.非同步預先處理聲音
std::thread線程Cocos2d-x中有很多現實的應用,非同步預先處理聲音,非同步載入一些資源資源檔,非同步載入圖片紋理Cocos2d-x為我們提供了API,但是它們非同步載入需要我們自己實現。下面我們介紹一下非同步預先處理聲音。
我們在前面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::applicationDidFinishLaunching()函數中,我們根據需要在合適的地方建立。
第②行代碼_loadingAudioThread->join()是合并線程到主線程,這個處理是在解構函式中調用的,join()函數一般是線上程處理完成後調用,我們可以在解構函式中調用,也可以在一些退出函數(如Layer的onExit函數)中調用。由於是_loadingAudioThread動態對象指標類型,需要釋放對象,我們可以通過第③行代碼CC_SAFE_DELETE(_loadingAudioThread)釋放。CC_SAFE_DELETE宏的作用如下:
delete_loadingAudioThread;
_loadingAudioThread = nullptr;

第④行代碼AppDelegate::loadingAudio()定義了線程回呼函數,我們在這個函數中預先處理聲音。


更多內容請關注國內第一本Cocos2d-x 3.2版本圖書《Cocos2d-x實戰:C++卷》本書交流討論網站:http://www.cocoagame.net
更多精彩視頻課程請關注智捷課堂Cocos課程:http://v.51work6.com
歡迎加入Cocos2d-x技術討論群:257760386歡迎關注智捷iOS課堂公用平台


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.