cocos2dx多线程以及线程同步 与 cocos2dx内存管理与多线程问题

ocos2d-x引擎在内部实现了一个庞大的主循环,每帧之间更新界面,如果耗时的操作放到了主线程中,游戏的界面就会卡,这是不能容忍的,游戏最基本的条件就是流畅性,这就是为什么游戏开发选择C++的原因。另外现在双核手机和四核手机越来越普遍了,是时候使用多线程来挖掘硬件的潜力了。

1.环境搭建

cocos2d-x中的多线程使用pthread就可以实现跨平台,而且也不是很难理解。使用pthread需要先配置一下工程。右击工程----->属性----->配置属性---->链接器----->输入---->附加依赖项中添加pthreadVCE2.lib,如下图


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


这样,环境就搭建起来了。

2.多线程的使用

使用pthread来实现多线程,最重要的一个函数是

[cpp]  view plain copy
  1. PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid,//线程的标示   
  2.                             const pthread_attr_t * attr,      //创建线程的参数   
  3.                             void *(*start) (void *),          //入口函数的指针   
  4.                             void *arg);                       //传递给线程的数据  
[cpp]  view plain copy
  1. PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid,//线程的标示  
  2.                             const pthread_attr_t * attr,      //创建线程的参数  
  3.                             void *(*start) (void *),          //入口函数的指针  
  4.                             void *arg);                       //传递给线程的数据  

在HelloWorldScene.h文件中

[cpp]  view plain copy
  1. pthread_t pidrun,pidgo;  
  2. static void* th_run(void *r);  
  3. static void* th_go(void *r);  
[cpp]  view plain copy
  1. pthread_t pidrun,pidgo;  
  2. static void* th_run(void *r);  
  3. static void* th_go(void *r);  
定义了两个函数和两个线程的标识。

然后自定义了一个类,用于给线程传递数据。Student类如下:

[cpp]  view plain copy
  1. #pragma once   
  2. #include <string>   
  3. class Student  
  4. {  
  5. public:  
  6.     Student(void);  
  7.     Student(std::string name,int age,std::string sex);  
  8.     ~Student(void);  
  9.   
  10.     std::string name;  
  11.     int age;  
  12.     std::string sex;  
  13.   
  14. };  
[cpp]  view plain copy
  1. #pragma once  
  2. #include <string>  
  3. class Student  
  4. {  
  5. public:  
  6.     Student(void);  
  7.     Student(std::string name,int age,std::string sex);  
  8.     ~Student(void);  
  9.   
  10.     std::string name;  
  11.     int age;  
  12.     std::string sex;  
  13.   
  14. };  

源文件如下

[cpp]  view plain copy
  1. #include "Student.h"   
  2. #include "cocos2d.h"   
  3.   
  4. Student::Student(void)  
  5. {  
  6. }  
  7.   
  8.   
  9. Student::~Student(void)  
  10. {  
  11.     cocos2d::CCLog("delete data");  
  12. }  
  13. Student::Student(std::string name,int age,std::string sex)  
  14. {  
  15.     this->name=name;  
  16.     this->age=age;  
  17.     this->sex=sex;  
  18. }  
[cpp]  view plain copy
  1. #include "Student.h"  
  2. #include "cocos2d.h"  
  3.   
  4. Student::Student(void)  
  5. {  
  6. }  
  7.   
  8.   
  9. Student::~Student(void)  
  10. {  
  11.     cocos2d::CCLog("delete data");  
  12. }  
  13. Student::Student(std::string name,int age,std::string sex)  
  14. {  
  15.     this->name=name;  
  16.     this->age=age;  
  17.     this->sex=sex;  
  18. }  
在退出菜单的回调函数中启动两个线程:

[cpp]  view plain copy
  1. void HelloWorld::menuCloseCallback(CCObject* pSender)  
  2. {  
  3.      
  4.     Student *temp=new Student(std::string("zhycheng"),23,std::string("male"));  
  5.     pthread_mutex_init(&mutex,NULL);  
  6.     pthread_create(&pidrun,NULL,th_run,temp);//启动线程   
  7.     pthread_create(&pidgo,NULL,th_go,0);  
  8.   
  9. }  
[cpp]  view plain copy
  1. void HelloWorld::menuCloseCallback(CCObject* pSender)  
  2. {  
  3.      
  4.     Student *temp=new Student(std::string("zhycheng"),23,std::string("male"));  
  5.     pthread_mutex_init(&mutex,NULL);  
  6.     pthread_create(&pidrun,NULL,th_run,temp);//启动线程  
  7.     pthread_create(&pidgo,NULL,th_go,0);  
  8.   
  9. }  

可以看到,将Student的指针传递给了pidrun线程,那么在pidrun线程中获得Student信息如下:

[cpp]  view plain copy
  1.        Student *s=(Student*)(r);  
  2. CCLog("name is %s,and age is %d,sex is %s",s->name.c_str(),s->age,s->sex.c_str());  
  3. delete s;  
[cpp]  view plain copy
  1.        Student *s=(Student*)(r);  
  2. CCLog("name is %s,and age is %d,sex is %s",s->name.c_str(),s->age,s->sex.c_str());  
  3. delete s;  

3.线程同步

使用了线程,必然就要考虑到线程同步,不同的线程同时访问资源的话,访问的顺序是不可预知的,会造成不可预知的结果。

这里使用pthread_mutex_t来实现同步,下面我来演示一下使用多线程实现卖票系统。卖票的时候,是由多个窗口同时卖票,这里要做到一张票不要卖出去两次,不要出现有票却无法卖的结果。

在线程函数th_run和th_go中来卖票,票的数量是一个全局变量,每卖出去一张票,就将票的数量减一。其中同步的pthread_mutex_t也是一个全局变量,就用它来实现线程同步。

[cpp]  view plain copy
  1. void* HelloWorld::th_run(void *r)  
  2. {  
  3.       
  4.     Student *s=(Student*)(r);  
  5.     CCLog("name is %s,and age is %d,sex is %s",s->name.c_str(),s->age,s->sex.c_str());  
  6.     delete s;  
  7.     while(true)  
  8.     {  
  9.         pthread_mutex_lock(&mutex);  
  10.         if(ticket>0)  
  11.         {  
  12.         CCLog("thread run sell %d",ticket);  
  13.         ticket--;  
  14.         pthread_mutex_unlock(&mutex);  
  15.         }  
  16.         else  
  17.         {  
  18.             pthread_mutex_unlock(&mutex);  
  19.             break;    
  20.         }  
  21.       
  22.         Sleep(1);  
  23.         //Usleep(10);   
  24.     }  
  25.   
  26.     return NULL;  
  27. }  
[cpp]  view plain copy
  1. void* HelloWorld::th_run(void *r)  
  2. {  
  3.       
  4.     Student *s=(Student*)(r);  
  5.     CCLog("name is %s,and age is %d,sex is %s",s->name.c_str(),s->age,s->sex.c_str());  
  6.     delete s;  
  7.     while(true)  
  8.     {  
  9.         pthread_mutex_lock(&mutex);  
  10.         if(ticket>0)  
  11.         {  
  12.         CCLog("thread run sell %d",ticket);  
  13.         ticket--;  
  14.         pthread_mutex_unlock(&mutex);  
  15.         }  
  16.         else  
  17.         {  
  18.             pthread_mutex_unlock(&mutex);  
  19.             break;    
  20.         }  
  21.       
  22.         Sleep(1);  
  23.         //Usleep(10);  
  24.     }  
  25.   
  26.     return NULL;  

来自:http://blog.csdn.net/kaitiren/article/details/14453313

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值