【玩转cocos2d-x之二十二】多线程和同步02-售票

原创作品,转载请标明http://www.jb51.cc/article/p-ntfjuwne-ep.html


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. classCTestLayer:
  3. publiccclayer
  4. {
  5. public:
  6. CTestLayer(void);
  7. ~CTestLayer(void);
  8. CREATE_FUNC(CTestLayer);
  9. virtualboolinit();
  10. pthread_tsellA_pid,sellB_pid;//线程id
  11. staticinttickets;//票数
  12. staticvoid*threadA(void*p);//线程A回调
  13. void*threadB(//线程B回调
  14. };
  15. //TestLayer.cpp
  16. #include"TestLayer.h"
  17. intCTestLayer::tickets=100;//初始化票数100
  18. CTestLayer::CTestLayer(void)
  19. {
  20. }
  21. CTestLayer::~CTestLayer(void)
  22. }
  23. boolCTestLayer::init()
  24. boolbRet=false;
  25. do
  26. CC_BREAK_IF(!cclayer::init());
  27. pthread_create(&sellA_pid,NULL,threadA,0);//创建线程A
  28. pthread_create(&sellB_pid,threadB,0); background-color:inherit">//创建线程B
  29. bRet=true;
  30. }while(0);
  31. returnbRet;
  32. void*CTestLayer::threadA(void*p)
  33. while(true)
  34. if(tickets>0)
  35. cclog("ASell%d",tickets--);//输出售票,每次减1
  36. else{
  37. break;
  38. returnNULL;
  39. void*CTestLayer::threadB(void*p)
  40. true)
  41. if(tickets>0)
  42. cclog("BSell%d",tickets--);
  43. else
  44. }
代码很简单,不多说了。我们来看一下输出,会发现有很多不可思议的现象出现,因为每个人每次运行的结果都不一样,所以这里不贴结果了,不可思议的现象可能有:

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

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

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

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

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

copy
    ASell36
  1. BSell36//卖2次了
  2. ASell35
  3. BSell34
  4. ASell33
  5. BSell32
  6. ASell30//提早卖了
  7. BSell31
  8. BSell28
  9. ASell29
  10. ASell27
  11. BSell26
  12. ASell25
  13. BSell24
  14. ASell23
  15. BSell22
  16. ASell21
  17. BSell20
  18. ASell19
  19. BSell18
  20. ASell17
  21. BSell16
  22. ASell15
  23. BSell14
  24. ASell13
  25. BSell12
  26. ASell11
  27. BSell10
  28. ASell9
  29. BSell8
  30. ASell7
  31. BSell6
  32. ASell5
  33. BSell4
  34. ASell3
  35. BSell2
  36. ASell1
  37. BSell0//站票。。。

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

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

3.1.初始化

在cpp外分配空间:

copy
    pthread_mutex_tCTestLayer::mutex;//mutex是静态成员变量

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

copy
    pthread_mutex_init(&mutex,NULL);

3.2.加锁和解锁

以线程A为例:

copy
    pthread_mutex_lock(&mutex);//加锁
  1. Sleep(100);
  2. pthread_mutex_unlock(&mutex);//解锁
  3. else{
  4. pthread_mutex_unlock(&mutex);//解锁
  5. }

3.3.释放

在当前层的析构函数中:

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

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

copy
    BSell16
  1. ASell15
  2. BSell14
  3. BSell13
  4. BSell12
  5. BSell11
  6. BSell10
  7. BSell9
  8. BSell8
  9. BSell7
  10. BSell6
  11. BSell5
  12. BSell4
  13. BSell3
  14. BSell2
  15. BSell1

4.源码下载

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

相关文章

    本文实践自 RayWenderlich、Ali Hafizji 的文章《...
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@1...
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从C...
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发...
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《...
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试...