今天我们要学习的就是cocos2d-x 多线程编程,对这方面还有不了解或者感兴趣的同学可以看一下。
先介绍一些基本的线程api就像每个进程有一个进程ID一样,每个线程也有一个线程ID,进程ID在整个系统中是唯一的,但线程不同,线程ID只在它所属的进程环境中有效。线程ID用pthread_t数据类型来表示,实现的时候可以用一个结构来代表pthread_t数据类型,所以可以移植的操作系统不能把它作为整数处理。因此必须使用函数来对来对两个线程ID进行比较。
1.名称:pthread_equal功能:比较两个线程ID
头文件:#include <pthread.h>
函数原形:int pthread_equal(pthread_t tid1,pthread_t tid2);
参数:tid1 进程1id, tid2 进程2id
返回值:若相等返回非0值,否则返回0
2.名称:pthread_self功能:获取自身线程的id
头文件:#include <pthread.h>
函数原形:pthread_t pthread_self(void);
参数:无
返回值:调用线程的线程id
线程的创建
3.名称:pthread_create功能:创建线程
头文件:#include <pthread.h>
函数原形:int pthread_create(pthread_t *restrict tidp,const pthread _attr_t *restrict attr,void *(*start_rtn)(void),void *restrict arg);
参数:
返回值:若成功返回则返回0,否则返回错误编号
举例:一个下载器的实例
- DownLoader.h
- //
- // DownLoader.h
- // MythLeague
- //
- //
- //
- /*
- * 1.开线程
- * 2.下载分配给自己的资源
- * 3.监听自己是否下载完
- * 4.和管理器交互
- */
- #ifndef __MythLeague__DownLoader__
- #define __MythLeague__DownLoader__
- #include "Global/Constants.h"
- typedef enum{
- DownloadStatus_Init,
- DownloadStatus_Loading,
- DownloadStatus_Success,
- DownloadStatus_FailedWhen_Init,
- DownloadStatus_FailedWhen_GetHandle,
- DownloadStatus_FailedWhen_GetInfo,
- }Enum_DownloadStatus;
- // 下载任务
- typedef struct {
- std :: string resUrl;
- std :: string fileName;
- }Struct_DownLoadTask;
- class DownLoader : public cocos2d::CCObject{ public: DownLoader();
- virtual ~DownLoader();
- CREATE_FUNC(DownLoader);
- bool init(); //下载资源
- void downloadRes(Struct_DownLoadTask p_downloadTask); //开线程
- static void* startNewThread(void* args);
- bool startDownload(); //处理下载数据
- static size_t process_data(void *buffer, size_t size, size_t nmemb, std::string& user_p); //监测下载完毕
- void checkDownloadStatus(float p_delay);
- public: Struct_DownLoadTask m_downloadTask; Enum_DownloadStatus m_iDownloadStatus; };
- #endif /* defined(__MythLeague__DownLoader__) */
- #include "DownLoader.h"
- #include "DownloadMgr.h"
- #include "Global/Tools.h"
- #define FILE_EXIST (200)
- #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
- #include "CURL/curl.h"
- #elif (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
- #include "platform/third_party/win32/curl/curl.h"
- #elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
- #include "platform/third_party/android/modules/libcurl/include/curl/curl.h"
- #endif
- using namespace std;
- using namespace cocos2d;
- #define DownLoader_Check_Interval (0.5f)
- DownLoader::DownLoader(){
- m_iDownloadStatus = DownloadStatus_Init;
- }
- DownLoader::~DownLoader(){
- }
- bool DownLoader::init(){
- return true;
- }
- //下载资源
- void DownLoader::downloadRes(Struct_DownLoadTask p_downloadTask){
- m_downloadTask = p_downloadTask;
- pthread_t l_pid;
- pthread_attr_t l_attr;
- pthread_attr_init(&l_attr);
- int l_iPriority = sched_get_priority_max(SCHED_OTHER);
- pthread_attr_setschedpolicy(&l_attr, l_iPriority);
- pthread_create(&l_pid, &l_attr, DownLoader::startNewThread, this);
- CCDirector::sharedDirector()->getScheduler()->scheduleSelector(schedule_selector(DownLoader::checkDownloadStatus), this, DownLoader_Check_Interval, false);
- }
- //开线程(静态方法)
- void* DownLoader::startNewThread(void* p_args){
- //线程独立
- pthread_detach(pthread_self());
- //自己新线程里下载
- DownLoader* l_thisDownloader = (DownLoader*)p_args;
- l_thisDownloader->startDownload();
- return NULL;
- }
- bool DownLoader::startDownload(){
- m_iDownloadStatus = DownloadStatus_Loading;
- #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
- // 初始化libcurl
- CURLcode return_code;
- return_code = curl_global_init(CURL_GLOBAL_ALL);
- if (CURLE_OK != return_code)
- {
- CCLog("init libcurl failed.");
- curl_global_cleanup();
- m_iDownloadStatus = DownloadStatus_FailedWhen_Init;
- return false;
- }
- // 获取easy handle
- CURL *easy_handle = curl_easy_init();
- if (NULL == easy_handle)
- {
- CCLog("get a easy handle failed.");
- curl_easy_cleanup(easy_handle);
- curl_global_cleanup();
- m_iDownloadStatus = DownloadStatus_FailedWhen_GetHandle;
- return false;
- }
- // 设置easy handle属性
- return_code = curl_easy_setopt(easy_handle, CURLOPT_URL, m_downloadTask.resUrl.c_str());
- //设置回调函数
- //return_code = curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, &process_data);
- curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, process_data);
- //回调函数的额外参数
- std::string connectx;
- return_code = curl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, &connectx);
- // 执行数据请求
- return_code = curl_easy_perform(easy_handle);
- //判断获取响应的http地址是否存在,若存在则返回200,400以上则为不存在,一般不存在为404错误
- int retcode = 0;
- return_code = curl_easy_getinfo(easy_handle, CURLINFO_RESPONSE_CODE , &retcode);
- if (CURLE_OK == return_code && FILE_EXIST == retcode)
- {
- double length = 0;
- return_code = curl_easy_getinfo(easy_handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD , &length);
- string l_fullPath = Tools::getWritableFilePath(m_downloadTask.fileName.c_str());
- FILE *fp = fopen(l_fullPath.c_str(), "wb+");
- if(fp != NULL){
- fwrite(connectx.c_str(), 1, length, fp);//返回实际写入文本的长度,若不等于length则写文件发生错误.
- fclose(fp);
- }else{
- CCLog("error here file: %s line: %d", __FILE__, __LINE__);
- }
- }
- else
- {
- CCLog("......url文件不存在!");
- curl_easy_cleanup(easy_handle);
- curl_global_cleanup();
- m_iDownloadStatus = DownloadStatus_FailedWhen_GetInfo;
- return false;
- }
- // 释放资源
- curl_easy_cleanup(easy_handle);
- curl_global_cleanup();
- #endif
- m_iDownloadStatus = DownloadStatus_Success;
- return 0;
- }
- //处理下载数据
- size_t DownLoader::process_data(void *buffer, size_t size, size_t nmemb, std::string& user_p){
- user_p.append((char*)buffer, size*nmemb);
- return size*nmemb;
- }
- //监测下载完毕
- void DownLoader::checkDownloadStatus(float p_delay){
- if (m_iDownloadStatus >= DownloadStatus_Success) {
- CCDirector::sharedDirector()->getScheduler()->unscheduleSelector(schedule_selector(DownLoader::checkDownloadStatus), this);
- //成功回调
- if (m_iDownloadStatus == DownloadStatus_Success) {
- DownloadMgr::sharedMgr()->callWhenDownloaderFinish_success(this);
- }
- //失败回调
- else{
- DownloadMgr::sharedMgr()->callWhenDownloaderFinish_failed(this);
- }
- }
- }
其它需要做的还有,需要写一个下载管理器,管理器的基本功能要包括
/*
* 1. 管理下载器 , 一个或多个
* 2. 显示 DownLoading 及进度
* 并屏蔽事件
* 3. 与外部交互的接口
*/