cocos2d-x 多线程以及线程同步
转自:http://blog.csdn.net/zhy_cheng/article/details/9116479
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"),,std::string("male"));
pthread_mutex_init(&mutex,NULL);
pthread_create(&pidrun,NULL,th_run,temp);//启动线程
pthread_create(&pidgo,NULL,th_go,); }
可以看到,将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>)
{
CCLog("thread run sell %d",ticket);
ticket--;
pthread_mutex_unlock(&mutex);
}
else
{
pthread_mutex_unlock(&mutex);
break;
} Sleep();
//Usleep(10);
} return NULL;
}
void* HelloWorld::th_go(void *r)
{ while(true)
{
pthread_mutex_lock(&mutex);
if(ticket>)
{
CCLog("thread go sell %d",ticket);
ticket--;
pthread_mutex_unlock(&mutex);
}
else
{
pthread_mutex_unlock(&mutex);
break; } Sleep(); }
return NULL;
}
mutex被锁定后,其他线程若再想锁定mutex的话,必须等待,当该线程释放了mutex之后,其他线程才能锁定mutex。Sleep()函数可以使得该线程休眠,单位是毫秒。下面是卖票的结果:
name is zhycheng,and age is ,sex is male
delete data
thread run sell
thread run sell
thread go sell
thread go sell
thread run sell
thread go sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread run sell
thread go sell
thread run sell
thread run sell
thread go sell
thread run sell
thread run sell
thread run sell
thread run sell
thread go sell
thread run sell
thread run sell
thread go sell
thread run sell
thread run sell
thread run sell
thread run sell
thread run sell
thread run sell
thread go sell
thread run sell
thread go sell
thread go sell
thread run sell
thread go sell
thread run sell
thread run sell
thread go sell
thread run sell
thread go sell
thread go sell
thread run sell
thread go sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread go sell
thread run sell
thread go sell
thread run sell
thread run sell
可以看到,这个打印结果正确无误。如果不加mutex会是什么样的结果呢,我将线程同步的mutex注释掉,输出的结果为:
name is zhycheng,and age is ,sex is male
delete data
thread run sell
thread run sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread run sell
thread go sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread run sell
thread go sell
thread run sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread go sell
thread run sell
thread go sell
thread go sell
thread run sell
thread go sell
thread go sell
thread run sell
thread go sell
thread run sell
thread run sell
thread run sell
thread run sell
thread run sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread go sell
thread run sell
thread run sell 43thread go sell thread run sell
thread go sell
thread go sell
thread run sell
thread run sell
thread go sell
thread go sell
thread run sell
thread go sell 33thread run sell thread go sell 31thread run sell thread go sell
thread run sell
thread go sell
thread run sell
thread go sell
thread run sell
thread run sell
thread go sell
thread run sell
thread go sell
thread go sell
thread run sell
thread run sell
thread go sell
thread go sell
thread run sell
thread run sell
thread go sell
thread run sell 11thread go sell thread go sell
thread run sell
thread run sell
thread go sell
thread go sell 5thread run sell thread go sell
thread run sell
thread go sell
thread run sell
可以看到,有的票卖了两次,有的票就没卖。
4.注意
1.Sleep()函数是使得线程休眠的函数,这个函数不跨平台,仅仅在windows上能用,其他平台使用usleep。
2.在非主线程中不能使用cocos2d-x管理内存的CCObject::retain(), CCObject::release() 者CCObject::autorelease(),因为CCAutoreleasePool不是线程安全的,OPENGL的上下文也不是线程安全的,所以不要再非主线程中使用cocos2d-x的API和UI操作。
cocos2d-x 多线程以及线程同步的更多相关文章
- C#多线程之线程同步篇3
在上一篇C#多线程之线程同步篇2中,我们主要学习了AutoResetEvent构造.ManualResetEventSlim构造和CountdownEvent构造,在这一篇中,我们将学习Barrier ...
- C#多线程之线程同步篇2
在上一篇C#多线程之线程同步篇1中,我们主要学习了执行基本的原子操作.使用Mutex构造以及SemaphoreSlim构造,在这一篇中我们主要学习如何使用AutoResetEvent构造.Manual ...
- C#多线程之线程同步篇1
在多线程(线程同步)中,我们将学习多线程中操作共享资源的技术,学习到的知识点如下所示: 执行基本的原子操作 使用Mutex构造 使用SemaphoreSlim构造 使用AutoResetEvent构造 ...
- 重新想象 Windows 8 Store Apps (46) - 多线程之线程同步: Lock, Monitor, Interlocked, Mutex, ReaderWriterLock
[源码下载] 重新想象 Windows 8 Store Apps (46) - 多线程之线程同步: Lock, Monitor, Interlocked, Mutex, ReaderWriterLoc ...
- 重新想象 Windows 8 Store Apps (47) - 多线程之线程同步: Semaphore, CountdownEvent, Barrier, ManualResetEvent, AutoResetEvent
[源码下载] 重新想象 Windows 8 Store Apps (47) - 多线程之线程同步: Semaphore, CountdownEvent, Barrier, ManualResetEve ...
- IOS 多线程,线程同步的三种方式
本文主要是讲述 IOS 多线程,线程同步的三种方式,更多IOS技术知识,请登陆疯狂软件教育官网. 一般情况下我们使用线程,在多个线程共同访问同一块资源.为保护线程资源的安全和线程访问的正确性. 在IO ...
- 关于Java多线程的线程同步和线程通信的一些小问题(顺便分享几篇高质量的博文)
Java多线程的线程同步和线程通信的一些小问题(顺便分享几篇质量高的博文) 前言:在学习多线程时,遇到了一些问题,这里我将这些问题都分享出来,同时也分享了几篇其他博客主的博客,并且将我个人的理解也分享 ...
- Java:多线程,线程同步,同步锁(Lock)的使用(ReentrantLock、ReentrantReadWriteLock)
关于线程的同步,可以使用synchronized关键字,或者是使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象.本文探讨Lock对象. synchronize ...
- MFC——9.多线程与线程同步
Lesson9:多线程与线程同步 程序.进程和线程是操作系统的重点,在计算机编程中.多线程技术是提高程序性能的重要手段. 本文主要解说操作系统中程序.进程和线程之间的关系,并通过相互排斥对象和事件对象 ...
随机推荐
- Java [Leetcode 101]Symmetric Tree
题目描述: Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). ...
- FFmpeg介绍及参数详细说明
FFmpeg是一个开源免费跨平台的视频和音频流方案,属于自由软件,采用LGPL或GPL许可证(依据你选择的组件).它提供了录制.转换以及流化音视频的完整解决方案.它包含了非常先进的音频/视频编解码库l ...
- DirectShow系统初级指南
流媒体的处理,以其复杂性和技术性,一向广受工业界的关注.特别伴随着因特网的普及,流媒体在网络上的广泛应用,怎样使流媒体的处理变得简单而富有成效逐渐成为了焦点问题.选择一种合适的应用方案,事半功倍.此时 ...
- 最简单的基于FFMPEG的转码程序
本文介绍一个简单的基于FFmpeg的转码器.它可以将一种视频格式(包括封转格式和编码格式)转换为另一种视频格式.转码器在视音频编解码处理的程序中,属于一个比较复杂的东西.因为它结合了视频的解码和编码. ...
- ios 照片编辑的view封装
转:http://www.cnblogs.com/xiaobaizhu/archive/2013/07/03/3170101.html 该控件有旋转,缩放,拖动,剪裁的功能,封装成了一个ImageCr ...
- spoj 694(后缀数组)
题意:求一个字符串的不重复子串的个数. 分析:对于下标为i的位置,能够产生的前缀子串个数为len-i(下标从0开始),对于与它字典序相邻的后缀产生的子串是重复的(就是他们的最长公共前缀),所以我们要减 ...
- HTTP协议学习笔记-2
HTTP报文 HTTP报文分为请求报文和响应报文(requeset and response) 请求报文的格式: <method> <request -URL> <ve ...
- linux常用命令之--文本编辑和文本内容查看命令
linux的文本编辑和文本内容查看命令 1.文本编辑命令 vi:用于编辑文本文件,基本上可以分为三种模式,分别是一般模式.编辑模式.命令行模式. 一般模式:当编辑一个文件时,刚进入文件就是一般模式. ...
- HDU 3311 Dig The Wells(斯坦纳树)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3311 [题意] 给定k座庙,n个其他点,m条边,点权代表挖井费用,边权代表连边费用,问使得k座庙里 ...
- 恒天云单节点部署指南--OpenStack H版本虚拟机单节点部署解决方案
本帖是openstack单节点在虚拟机上部署的实践.想要玩玩和学习openstack的小伙伴都看过来,尤其是那些部署openstack失败的小伙伴.本帖可以让你先领略一下openstack的魅力.本I ...