Multithreading concurrent access is not much used in the Cocos2d-x engine, mainly because the entire structure design is not multithreaded. Ref objects originating from objective-c need to use Autoreleasepool for memory management, Autoreleasepool is non-thread safe, all retain (), release () that do not recommend calling ref objects in child multi-threading and Autorelease () functions. Also, OpenGL context objects do not support thread safety.
But sometimes we need to load some resources asynchronously, such as loading image textures, sound preprocessing, and network request data. If the image texture is loaded asynchronously we can use the content described in section 20.4.41. But sound preprocessing and network request data need to be realized by multithreading technology.
The Cocos2d-x engine also provides multithreading technology, Cocos2d-x 3.x before using third-party pthread technology. Using Std::thread multithreading technology in the C++11 new specification after the Cocos2d-x 3.x, Std::thread is relatively simple to use.
1.std::thread Multithreading Technology
Std::thread is c++11 introduced a new line libraries, which provides thread management related functions, Std::mutex (mutex) is also provided in the Std::thread library, and thread synchronization can be achieved through Std::mutex.
Starting a new thread is very simple, and when we create a Std::thread object, it starts on its own. When you create a thread Std::thread object, you can provide a callback function for that thread. The following code implements callbacks for creating thread and thread functions:
#include <thread> #include <iostream>void callfn () {① std::cout << "Hello thread!" << std:: Endl;} int main () { std::thread T1 (CALLFN); ②t1.join (); ③ return 0;}
The above code, line ②, is the creation of the T1 thread object, whose arguments are the function pointer Callfn, and if necessary, we can also provide parameters for the callback function. The code ① line is the definition of the callback function. The ③ Line Code T1.join () merges the child thread with the main thread, which enables the child thread to execute before it can continue to execute the main thread, in order to prevent the child thread from executing and undoing the main thread's execution.
The creation thread can also allocate memory using the heap, with the following code:
void Callfn () { std::cout << "Hello thread!" << Std::endl;} int main () { std::thread* t1 = new std::thread (CALLFN), ①t1->join ();d eletet1;②t1 = Nullptr;③ return 0;}
The preceding code, line ①, allocates memory by heap, that is, by creating a dynamic thread object with the new operator. So we need to dispose of the object in the case of completion, and we use delete in the code ②.The T1 statement is released, and the release is completed to set the pointer variable through the code ③ line T1 = nullptr, which prevents the "wild pointer".
2. Asynchronous preprocessing sound
There are many practical applications in Std::thread threading Cocos2d-x, asynchronous preprocessing of sounds, asynchronous loading of some resource resource files, asynchronous loading of picture textures Cocos2d-x provide us with APIs, but their asynchronous loading requires our own implementation. Let's look at asynchronous preprocessing sounds.
We introduced sound preprocessing and purging in the previous 20.5 section, in which the preprocessing sound is synchronous, it causes the main thread to block and the user's feeling will be "stuck" for a moment. If this "card" is longer, we solve the main thread blocking problem, improve the user experience, we can preprocess the sound asynchronously.
We used Std::thread thread asynchronous preprocessing sound in the 20.5 section of the case, we can load asynchronously in appdelegate, and the modified AppDelegate.h code is as follows:
#include "Cocos2d.h"
#include "SimpleAudioEngine.h"
using namespace Cocosdenshion;
Class Appdelegate:private Cocos2d::application
{
Private
Std::thread *_loadingaudiothread;①
void Loadingaudio ();Ii
Public
Appdelegate ();
Virtual ~appdelegate ();
... ...
};
We declared the private std::thread thread pointer variable _loadingaudiothread in line ①. The ② code declares a private asynchronous preprocessing sound function Loadingaudio ().
The AppDelegate.cpp code after the modification is as follows:
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 () ④{//Initialize Music simpleaudioengine::getinstance ()->preloadbackgroundmusic ("sound/ Jazz.mp3 "); Simpleaudioengine::getinstance ()->preloadbackgroundmusic ("Sound/synth.mp3");//Initialize Sound Simpleaudioengine:: GetInstance ()->preloadeffect ("Sound/blip.wav");}
The above code, ①, creates a thread object in the constructor, and the thread object code can also be placed in the appdelegate::applicationdidfinishlaunching () function, which we create as needed in the appropriate place.
The ② Line Code _loadingaudiothread->join () is a merge thread to the primary thread, which is called in the destructor, and the join () function is usually called after the thread processing is complete, and we can call it in the destructor. It can also be called in some exit functions, such as the onexit function of a layer. Because it is a _loadingaudiothread dynamic object pointer type, the object needs to be disposed, and we can release it through the ③ Line code cc_safe_delete (_loadingaudiothread). The Cc_safe_delete macro works as follows:
Delete_loadingaudiothread;
_loadingaudiothread = nullptr;
The ④ Line Code appdelegate::loadingaudio () defines the thread callback function, in which we preprocess the sound.
For more information, please pay attention to the first Cocos2d-x 3.2 Edition book "Cocos2d-x: C + + volume" book Exchange discussionwebsite: http://www.c ocoagame.net
For more exciting video courses, please follow Cocos class: http://v.51work6.com
Welcome to join Cocos2d-x Technical Discussion group: 257760386 Welcome to Luxgen iOS Classroom public platform
Multi-threaded concurrent access in Cocos2d-x optimization