多线程

#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 BA B 在单独运行时都需要 10 秒来完成自己的任务,而且任务都是运算操作,线程 A B 之间没有竞争和共享数据的问题。现在让 A B 两个线程并行,则操作系统会不停的在 A B 两个线程之间切换,达到一种伪并行的效果。

//如果操作系统切换的频率是每秒一次,切换的成本是 0.1 秒(主要是栈切换),则总共需要 20 + 19 * 0.1 = 21.9 秒;如果使用协程的方式,可以先运行协程 AA 结束的时候让位给协程 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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值