转自博客:http://blog.csdn.net/zhy_cheng/article/details/9116479
购票问题,很好的展示了多线程的用武之地,为了方便快捷的进行工作的展开,多窗口售票才不会大排长龙……
首先,配置一下参数
右击工程----->属性----->配置属性---->链接器----->输入---->附加依赖项中添加pthreadVCE2.lib
添加附加包含目录,右击项目,属性----->C/C++---->常规----->附加包含目录加入pthread头文件所在的目录
多线程最重要的一个函数是
PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid,//线程的标示
const pthread_attr_t * attr, //创建线程的参数
void *(*start) (void *), //入口函数的指针
void *arg); //传递给线程的数据
学生类
//Student.h
#pragma once
#include <string>
using namespace std;
class Student
{
public:
Student(void);
~Student(void);
Student(string name, int age, string sex);
string name;
int age;
string sex;
};
//Student.cpp
#include "Student.h"
#include "cocos2d.h"
Student::Student(void)
{
}
Student::Student( string name, int age, string sex )
{
this->name = name;
this->age = age;
this->sex = sex;
}
Student::~Student(void)
{
cocos2d::CCLog("delete data");
}
HelloWorldScene.h
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
#include "Box2D/Box2D.h"
#include "SimpleAudioEngine.h"
#include "cocos-ext.h"
#include "pthread.h"
USING_NS_CC;
USING_NS_CC_EXT;
class HelloWorld : public cocos2d::CCLayer
{
public:
// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
virtual bool init();
// there's no 'id' in cpp, so we recommand to return the exactly class pointer
static cocos2d::CCScene* scene();
// a selector callback (修改)
void menuCloseCallback(CCObject* pSender);
// implement the "static node()" method manually
CREATE_FUNC(HelloWorld);
//test 多线程 (添加)
pthread_t pidrun, pidgo;
static void* th_run(void* r);
static void* th_go(void* r);
};
#endif // __HELLOWORLD_SCENE_H__
HelloWorldScene.cpp (没有写出的其他函数 内容不变)
static int ticket = 100;
static pthread_mutex_t mutex;
void HelloWorld::menuCloseCallback(CCObject* pSender)
{
// "close" menu item clicked
//CCDirector::sharedDirector()->end();
Student* temp = new Student("name", 24, "male");
pthread_mutex_init(&mutex, NULL);
pthread_create(&pidrun, NULL, th_run, temp);
pthread_create(&pidgo, NULL, th_go, 0);
}
void* HelloWorld::th_run(void* r)
{
Student* s = (Student*)(r);
CCLog("Student name = %s, age = %d, sex = %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);
return NULL;
}
#ifdef WIN32
Sleep(100);
#else
Usleep(1);
#endif
}
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);
return NULL;
}
#ifdef WIN32
Sleep(100);
#else
Usleep(1);
#endif
}
return NULL;
}
点击关闭按钮,查看控制台输出信息。
注意:文章中的
1.Sleep()函数是使得线程休眠的函数,这个函数不跨平台,仅仅在windows上能用,其他平台使用usleep。
2.在非主线程中不能使用cocos2d-x管理内存的CCObject::retain()
, CCObject::release()
者CCObject::autorelease(),因为CCAutoreleasePool不是线程安全的,OPENGL的上下文也不是线程安全的,所以不要再非主线程中使用cocos2d-x的API和UI操作。