#ifndef pthreadTest_hpp
#define pthreadTest_hpp
class pthreadTest : public cocos2d::Layer
{
public:
pthreadTest();
~pthreadTest();
static cocos2d::Scene* createScene();
virtual bool init();
CREATE_FUNC(pthreadTest);
pthread_t sellA_pid,sellB_pid;//线程id
static int tickets;//票数
static pthread_mutex_t mutex; //互斥锁
static void* threadA(void* p);//线程A回调
static void* threadB(void* p);//线程B回调
};
/*
//进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度。
//线程拥有自己独立的栈和共享的堆,共享堆,不共享栈,线程亦由操作系统调度(标准线程是的)。
//协程和线程一样共享堆,不共享栈,协程由程序员在协程的代码里显示调度。进程和其他两个的区别还是很明显的。
//协程和线程的区别是:协程避免了无意义的调度,由此可以提高性能,但也因此,程序员必须自己承担调度的责任,同时,协程也失去了标准线程使用多CPU的能力。
//假设有一个单核的操作系统,系统上没有其它的程序需要运行,现有两个线程 A 和 B,A 和 B 在单独运行时都需要 10 秒来完成自己的任务,而且任务都是运算操作,线程 A 和 B 之间没有竞争和共享数据的问题。现在让 A 和 B 两个线程并行,则操作系统会不停的在 A 和 B 两个线程之间切换,达到一种伪并行的效果。
//如果操作系统切换的频率是每秒一次,切换的成本是 0.1 秒(主要是栈切换),则总共需要 20 + 19 * 0.1 = 21.9 秒;如果使用协程的方式,可以先运行协程 A,A 结束的时候让位给协程 B,只发生一次切换,则总共需要 20 + 1 * 0.1 = 20.1 秒。如果操作系统是双核的,而且线程是标准线程,那么线程 A 和 B 可以达到真的并行,则总时间为 10 秒;而协程的方式仍然需要 20.1 秒的时间。
//这个问题主要是因为一个线程执行到一半的时候,时间片的切换导致另一个线程修改了同一个数据,当再次切换会原来线程并继续往下运行的时候,数据由于被修改了导致结果出错。所以我们要做的就是保证这个线程完全执行完,所以对线程加锁是个不错的注意,互斥对象mutex就是这个锁。
//所谓加锁,就是说当我们要访问某要害变量之前,都需要首先获得答应才能继续,假如未获得答应则只有等待。一个要害变量拥有一把锁,一个线程必须先得到这把锁(其实称为钥匙可能更形象)才可以访问这个变量,而当某个变量持有这把锁的时候,其他线程就不能反复的得到它,只有等持有锁的线程把锁归还以后其他线程才有可能得到它。之所以这样做,就是为了防止一个线程读取某对象途中另一线程对它进行了修改,或两线程同时对一变量进行修改。
*/
#endif /* pthreadTest_hpp */
#include "pthreadTest.hpp"
#include "pthread.h"
USING_NS_CC;
int pthreadTest::tickets=100;//初始化票数100
pthread_mutex_t pthreadTest::mutex;
pthreadTest::pthreadTest()
{
}
pthreadTest::~pthreadTest()
{
pthread_mutex_destroy(&mutex);//前提要保证是解锁状态,否则会返回16的错误,释放失败
}
Scene* pthreadTest::createScene()
{
auto scene = Scene::create();
auto layer = pthreadTest::create();
scene->addChild(layer);
return scene;
}
bool pthreadTest::init()
{
if ( !Layer::init() )
{
return false;
}
pthread_mutex_init(&mutex,NULL); //互斥锁 初始化
pthread_create(&sellA_pid,NULL,threadA,0);//创建线程A
pthread_create(&sellB_pid,NULL,threadB,0);//创建线程B
return true;
}
void* pthreadTest::threadA(void* p)
{
while(true)
{
pthread_mutex_lock(&mutex);//加锁
if(tickets>0)
{
sleep(1);
printf("A Sell %d\n",tickets--);//输出售票,每次减1
pthread_mutex_unlock(&mutex);//解锁
}
else {
// pthread_mutex_unlock(&mutex);//解锁
break;
}
}
return NULL;
}
void* pthreadTest::threadB(void* p)
{
while(true)
{
pthread_mutex_lock(&mutex);//加锁
if (tickets>0)
{
sleep(1);
printf("B Sell %d\n",tickets--);
pthread_mutex_unlock(&mutex);//解锁
}
else
{
// pthread_mutex_unlock(&mutex);//解锁
break;
}
}
return NULL;
}
运行结果:
A Sell 100
B Sell 99
A Sell 98
B Sell 97
A Sell 96
B Sell 95
A Sell 94
B Sell 93
A Sell 92
B Sell 91
A Sell 90
B Sell 89
A Sell 88