分享

玩转cocos2d-x ---多线程和同步

 it程序猿修养 2014-12-30

原创作者:偶尔e网事,转载请标明http://blog.csdn.net/jackystudio/article/details/14161151


pthread有很多不同应用,官网都有相应的API解释和Sample,这里不再重复,本文主要介绍一个cocos2d-x多线程和同步示例。


1.售票

孙鑫老师的C++和Java多线程售票一直让我念念不忘,好吧,这里用cocos2d-x和pthread实现一个吧。总共有100张火车票,有2个售票点A和B再售票,当票卖完了就结束了。我们知道当程序一开始进程就会创建一个主线程,所以可以在主线程基础上再创建2个线程A和B,再线程A和B中分别售票,当票数为0的时候,结束线程A和B。


2.多线程售票

  1. //TestLayer.h  
  2. class CTestLayer :  
  3.     public CCLayer  
  4. {  
  5. public:  
  6.     CTestLayer(void);  
  7.     ~CTestLayer(void);  
  8.   
  9.     CREATE_FUNC(CTestLayer);  
  10.     virtual bool init();  
  11.   
  12.     pthread_t sellA_pid,sellB_pid;//线程id  
  13.     static int tickets;//票数  
  14.   
  15.     static void* threadA(void* p);//线程A回调  
  16.     static void* threadB(void* p);//线程B回调  
  17. };  
  18.   
  19.   
  20. //TestLayer.cpp  
  21. #include "TestLayer.h"  
  22.   
  23. int CTestLayer::tickets=100;//初始化票数100  
  24. CTestLayer::CTestLayer(void)  
  25. {  
  26. }  
  27.   
  28.   
  29. CTestLayer::~CTestLayer(void)  
  30. {  
  31. }  
  32.   
  33. bool CTestLayer::init()  
  34. {  
  35.     bool bRet=false;  
  36.     do   
  37.     {  
  38.         CC_BREAK_IF(!CCLayer::init());  
  39.         pthread_create(&sellA_pid,NULL,threadA,0);//创建线程A  
  40.         pthread_create(&sellB_pid,NULL,threadB,0);//创建线程B  
  41.   
  42.         bRet=true;  
  43.     } while (0);  
  44.     return bRet;  
  45. }  
  46.   
  47. void* CTestLayer::threadA(void* p)  
  48. {  
  49.     while(true)  
  50.     {  
  51.         if(tickets>0)  
  52.         {  
  53.             CCLog("A Sell %d",tickets--);//输出售票,每次减1  
  54.         }  
  55.         else {  
  56.             break;  
  57.         }  
  58.     }  
  59.     return NULL;  
  60. }  
  61.   
  62. void* CTestLayer::threadB(void* p)  
  63. {  
  64.     while(true)  
  65.     {  
  66.         if (tickets>0)  
  67.         {  
  68.             CCLog("B Sell %d",tickets--);  
  69.         }  
  70.         else   
  71.         {  
  72.             break;  
  73.         }  
  74.     }  
  75.     return NULL;  
  76. }  
代码很简单,不多说了。我们来看一下输出,会发现有很多不可思议的现象出现,因为每个人每次运行的结果都不一样,所以这里不贴结果了,不可思议的现象可能有:

(1)同一张票卖了2次。

(2)后面的票比前面的票先卖出去。

(3)第0张票竟然也可以卖。(这算站票么。。。)

原因不多解释了,时间片的问题,不明白的Google之。如果你觉得不会有这么巧,那么在打印结果前加上这么一句:

  1. Sleep(100);  
人为干扰线程的运行,增大出错几率。结果可能会是这样:

  1. A Sell 36  
  2. B Sell 36//卖2次了  
  3. A Sell 35  
  4. B Sell 34  
  5. A Sell 33  
  6. B Sell 32  
  7. A Sell 30//提早卖了  
  8. B Sell 31  
  9. B Sell 28  
  10. A Sell 29  
  11. A Sell 27  
  12. B Sell 26  
  13. A Sell 25  
  14. B Sell 24  
  15. A Sell 23  
  16. B Sell 22  
  17. A Sell 21  
  18. B Sell 20  
  19. A Sell 19  
  20. B Sell 18  
  21. A Sell 17  
  22. B Sell 16  
  23. A Sell 15  
  24. B Sell 14  
  25. A Sell 13  
  26. B Sell 12  
  27. A Sell 11  
  28. B Sell 10  
  29. A Sell 9  
  30. B Sell 8  
  31. A Sell 7  
  32. B Sell 6  
  33. A Sell 5  
  34. B Sell 4  
  35. A Sell 3  
  36. B Sell 2  
  37. A Sell 1  
  38. B Sell 0//站票。。。  

3.利用互斥对象同步数据

这个问题主要是因为一个线程执行到一半的时候,时间片的切换导致另一个线程修改了同一个数据,当再次切换会原来线程并继续往下运行的时候,数据由于被修改了导致结果出错。所以我们要做的就是保证这个线程完全执行完,所以对线程加锁是个不错的注意,互斥对象mutex就是这个锁。

3.1.初始化

在cpp外分配空间:

  1. pthread_mutex_t CTestLayer::mutex;//mutex是静态成员变量  

在init中初始化,动态初始化:

  1. pthread_mutex_init(&mutex,NULL);  

3.2.加锁和解锁

以线程A为例:

  1. void* CTestLayer::threadA(void* p)  
  2. {  
  3.     while(true)  
  4.     {  
  5.         pthread_mutex_lock(&mutex);//加锁  
  6.         if(tickets>0)  
  7.         {  
  8.             Sleep(100);  
  9.             CCLog("A Sell %d",tickets--);  
  10.             pthread_mutex_unlock(&mutex);//解锁  
  11.         }  
  12.         else {  
  13.             pthread_mutex_unlock(&mutex);//解锁  
  14.             break;  
  15.         }  
  16.     }  
  17.     return NULL;  
  18. }  

3.3.释放

在当前层的析构函数中:

  1. pthread_mutex_destroy(&mutex);//前提要保证是解锁状态,否则会返回16的错误,释放失败  

这个时候再看一下结果,Bingo!

  1. B Sell 16  
  2. A Sell 15  
  3. B Sell 14  
  4. B Sell 13  
  5. B Sell 12  
  6. B Sell 11  
  7. B Sell 10  
  8. B Sell 9  
  9. B Sell 8  
  10. B Sell 7  
  11. B Sell 6  
  12. B Sell 5  
  13. B Sell 4  
  14. B Sell 3  
  15. B Sell 2  
  16. B Sell 1  

4.源码下载

http://download.csdn.net/detail/jackyvincefu/6503759

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多