标签:blog   http   os   ar   使用   strong   sp   文件   数据   
cocos2d-x引擎在内部实现了一个庞大的主循环,每帧之间更新界面,如果耗时的操作放到了主线程中,游戏的界面就会卡,这是不能容忍的,游戏最基本的条件就是流畅性,这就是为什么游戏开发选择C++的原因。另外现在双核手机和四核手机越来越普遍了,是时候使用多线程来挖掘硬件的潜力了。
1.环境搭建
cocos2d-x中的多线程使用pthread就可以实现跨平台,而且也不是很难理解。使用pthread需要先配置一下工程。右击工程----->属性----->配置属性---->链接器----->输入---->附加依赖项中添加pthreadVCE2.lib,如下图

接着添加附加包含目录,右击项目,属性----->C/C++---->常规----->附加包含目录加入pthread头文件所在的目录

这样,环境就搭建起来了。
2.多线程的使用
使用pthread来实现多线程,最重要的一个函数是
 
- PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid,
-                             const pthread_attr_t * attr,      
-                             void *(*start) (void *),          
-                             void *arg);                       
 
在HelloWorldScene.h文件中
 
 
- pthread_t pidrun,pidgo;  
- static void* th_run(void *r);  
- static void* th_go(void *r);  
 
定义了两个函数和两个线程的标识。
 
然后自定义了一个类,用于给线程传递数据。Student类如下:
 
- #pragma once  
- #include <string>  
- class Student  
- {  
- public:  
-     Student(void);  
-     Student(std::string name,int age,std::string sex);  
-     ~Student(void);  
-   
-     std::string name;  
-     int age;  
-     std::string sex;  
-   
- };  
 
源文件如下
 
 
- #include "Student.h"  
- #include "cocos2d.h"  
-   
- Student::Student(void)  
- {  
- }  
-   
-   
- Student::~Student(void)  
- {  
-     cocos2d::CCLog("delete data");  
- }  
- Student::Student(std::string name,int age,std::string sex)  
- {  
-     this->name=name;  
-     this->age=age;  
-     this->sex=sex;  
- }  
 
在退出菜单的回调函数中启动两个线程:
 
 
- void HelloWorld::menuCloseCallback(CCObject* pSender)  
- {  
-      
-     Student *temp=new Student(std::string("zhycheng"),23,std::string("male"));  
-     pthread_mutex_init(&mutex,NULL);  
-     pthread_create(&pidrun,NULL,th_run,temp);
-     pthread_create(&pidgo,NULL,th_go,0);  
-   
- }  
 
可以看到,将Student的指针传递给了pidrun线程,那么在pidrun线程中获得Student信息如下:
 
 
-        Student *s=(Student*)(r);  
- CCLog("name is %s,and age is %d,sex is %s",s->name.c_str(),s->age,s->sex.c_str());  
- delete s;  
 
 
 
3.线程同步
使用了线程,必然就要考虑到线程同步,不同的线程同时访问资源的话,访问的顺序是不可预知的,会造成不可预知的结果。
 
这里使用pthread_mutex_t来实现同步,下面我来演示一下使用多线程实现卖票系统。卖票的时候,是由多个窗口同时卖票,这里要做到一张票不要卖出去两次,不要出现有票却无法卖的结果。
在线程函数th_run和th_go中来卖票,票的数量是一个全局变量,每卖出去一张票,就将票的数量减一。其中同步的pthread_mutex_t也是一个全局变量,就用它来实现线程同步。
 
- void* HelloWorld::th_run(void *r)  
- {  
-       
-     Student *s=(Student*)(r);  
-     CCLog("name is %s,and age is %d,sex is %s",s->name.c_str(),s->age,s->sex.c_str());  
-     delete s;  
-     while(true)  
-     {  
-         pthread_mutex_lock(&mutex);  
-         if(ticket>0)  
-         {  
-         CCLog("thread run sell %d",ticket);  
-         ticket--;  
-         pthread_mutex_unlock(&mutex);  
-         }  
-         else  
-         {  
-             pthread_mutex_unlock(&mutex);  
-             break;    
-         }  
-       
-         Sleep(1);  
-         
-     }  
-   
-     return NULL;  
- }  
 
 
- void* HelloWorld::th_go(void *r)  
- {  
-       
-     while(true)  
-     {  
-         pthread_mutex_lock(&mutex);  
-         if(ticket>0)  
-         {  
-         CCLog("thread go sell %d",ticket);  
-         ticket--;  
-         pthread_mutex_unlock(&mutex);  
-         }  
-         else  
-         {  
-             pthread_mutex_unlock(&mutex);  
-             break;  
-               
-         }  
-           
-         Sleep(1);  
-           
-     }  
-     return NULL;  
- }  
 
 
 
mutex被锁定后,其他线程若再想锁定mutex的话,必须等待,当该线程释放了mutex之后,其他线程才能锁定mutex。Sleep()函数可以使得该线程休眠,单位是毫秒。下面是卖票的结果:
 
 
 
 
可以看到,这个打印结果正确无误。如果不加mutex会是什么样的结果呢,我将线程同步的mutex注释掉,输出的结果为:
 
 
可以看到,有的票卖了两次,有的票就没卖。
 
4.注意
1.Sleep()函数是使得线程休眠的函数,这个函数不跨平台,仅仅在windows上能用,其他平台使用usleep。
2.在非主线程中不能使用cocos2d-x管理内存的CCObject::retain(), CCObject::release() 者CCObject::autorelease(),因为CCAutoreleasePool不是线程安全的,OPENGL的上下文也不是线程安全的,所以不要再非主线程中使用cocos2d-x的API和UI操作。
 
最后工程的源代码下载:http://download.csdn.net/detail/zhy_cheng/5600979
转自:http://blog.csdn.net/zhy_cheng/article/details/9116479
多线程以及线程同步
标签:blog   http   os   ar   使用   strong   sp   文件   数据   
原文地址:http://www.cnblogs.com/C-Plus-Plus/p/4037654.html