加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

cocos2dx多线程以及线程同步 与 cocos2dx内存管理与多线程问题

发布时间:2020-12-14 19:18:43 所属栏目:百科 来源:网络整理
导读:cocos2dx多线程以及线程同步 与 cocos2dx内存管理与多线程问题 分类:移动研发COCOS2DX移动ANDROID研发 IOS研发 2013-11-07 16:17 7573人阅读 评论(5) 收藏 举报 目录(?) [+] cocos2d-x引擎在内部实现了一个庞大的主循环,每帧之间更新界面,如果耗时的操作

cocos2dx多线程以及线程同步 与 cocos2dx内存管理与多线程问题

分类:移动研发COCOS2DX移动ANDROID研发 IOS研发 7573人阅读 评论(5) 收藏 举报

目录(?)[+]

cocos2d-x引擎在内部实现了一个庞大的主循环,每帧之间更新界面,如果耗时的操作放到了主线程中,游戏的界面就会卡,这是不能容忍的,游戏最基本的条件就是流畅性,这就是为什么游戏开发选择C++的原因。另外现在双核手机和四核手机越来越普遍了,是时候使用多线程来挖掘硬件的潜力了。

1.环境搭建

cocos2d-x中的多线程使用pthread就可以实现跨平台,而且也不是很难理解。使用pthread需要先配置一下工程。右击工程----->属性----->配置属性---->链接器----->输入---->附加依赖项中添加pthreadVCE2.lib,如下图


接着添加附加包含目录,右击项目,属性----->C/C++---->常规----->附加包含目录加入pthread头文件所在的目录


这样,环境就搭建起来了。

2.多线程的使用

使用pthread来实现多线程,最重要的一个函数是

[cpp] view plain copy
  1. PTW32_DLLPORTintPTW32_CDECLpthread_create(pthread_t*tid,//线程的标示
  2. constpthread_attr_t*attr,0); background-color:inherit">//创建线程的参数
  3. void*(*start)(void*),0); background-color:inherit">//入口函数的指针
  4. void*arg);//传递给线程的数据
[cpp] view plain copy
    PTW32_DLLPORTintPTW32_CDECLpthread_create(pthread_t*tid,//线程的标示
  1. constpthread_attr_t*attr,0); background-color:inherit">//创建线程的参数
  2. void*(*start)(void*),0); background-color:inherit">//入口函数的指针
  3. void*arg);//传递给线程的数据

在HelloWorldScene.h文件中

copy
    pthread_tpidrun,pidgo;
  1. staticvoid*th_run(void*r);
  2. void*th_go(void*r);
copy
    pthread_tpidrun,pidgo;
  1. staticvoid*th_run(void*r);
  2. void*th_go(void*r);
定义了两个函数和两个线程的标识。

然后自定义了一个类,用于给线程传递数据。Student类如下:

copy
    #pragmaonce
  1. #include<string>
  2. classStudent
  3. {
  4. public:
  5. Student(void);
  6. Student(std::stringname,intage,std::stringsex);
  7. ~Student(
  8. std::stringname;
  9. intage;
  10. std::stringsex;
  11. };
copy
    #pragmaonce
  1. #include<string>
  2. classStudent
  3. {
  4. public:
  5. Student(void);
  6. Student(std::stringname,87); background-color:inherit; font-weight:bold">intage,std::stringsex);
  7. ~Student(
  8. std::stringname;
  9. intage;
  10. std::stringsex;
  11. };

源文件如下

copy
    #include"Student.h"
  1. #include"cocos2d.h"
  2. Student::Student(void)
  3. {
  4. }
  5. Student::~Student(void)
  6. cocos2d::CCLog("deletedata");
  7. Student::Student(std::stringname,std::stringsex)
  8. this->name=name;
  9. this->age=age;
  10. this->sex=sex;
  11. }
copy
    #include"Student.h"
  1. #include"cocos2d.h"
  2. Student::Student(void)
  3. {
  4. }
  5. Student::~Student(void)
  6. cocos2d::CCLog("deletedata");
  7. Student::Student(std::stringname,std::stringsex)
  8. this->name=name;
  9. this->age=age;
  10. this->sex=sex;
  11. }
在退出菜单的回调函数中启动两个线程:

copy
    voidHelloWorld::menuCloseCallback(CCObject*pSender)
  1. Student*temp=newStudent(std::string("zhycheng"),23,std::string("male"));
  2. pthread_mutex_init(&mutex,NULL);
  3. pthread_create(&pidrun,NULL,th_run,temp);//启动线程
  4. pthread_create(&pidgo,th_go,0);
  5. }
copy
    voidHelloWorld::menuCloseCallback(CCObject*pSender)
  1. Student*temp=newStudent(std::string("zhycheng"),std::string("male"));
  2. pthread_mutex_init(&mutex,NULL);
  3. pthread_create(&pidrun,0); background-color:inherit">//启动线程
  4. pthread_create(&pidgo,0);
  5. }

可以看到,将Student的指针传递给了pidrun线程,那么在pidrun线程中获得Student信息如下:

copy
    Student*s=(Student*)(r);
  1. CCLog("nameis%s,andageis%d,sexis%s",s->name.c_str(),s->age,s->sex.c_str());
  2. deletes;
copy
    Student*s=(Student*)(r);
  1. CCLog("nameis%s,sexis%s",s->sex.c_str());
  2. deletes;

3.线程同步

使用了线程,必然就要考虑到线程同步,不同的线程同时访问资源的话,访问的顺序是不可预知的,会造成不可预知的结果。

这里使用pthread_mutex_t来实现同步,下面我来演示一下使用多线程实现卖票系统。卖票的时候,是由多个窗口同时卖票,这里要做到一张票不要卖出去两次,不要出现有票却无法卖的结果。

在线程函数th_run和th_go中来卖票,票的数量是一个全局变量,每卖出去一张票,就将票的数量减一。其中同步的pthread_mutex_t也是一个全局变量,就用它来实现线程同步。

copy
    void*HelloWorld::th_run(void*r)
  1. Student*s=(Student*)(r);
  2. CCLog("nameis%s,s->sex.c_str());
  3. deletes;
  4. while(true)
  5. pthread_mutex_lock(&mutex);
  6. if(ticket>0)
  7. CCLog("threadrunsell%d",ticket);
  8. ticket--;
  9. pthread_mutex_unlock(&mutex);
  10. }
  11. else
  12. break;
  13. Sleep(1);
  14. //Usleep(10);
  15. returnNULL;
  16. copy
      void*HelloWorld::th_run(void*r)
    1. Student*s=(Student*)(r);
    2. CCLog("nameis%s,s->sex.c_str());
    3. deletes;
    4. while(true)
    5. pthread_mutex_lock(&mutex);
    6. if(ticket>0)
    7. CCLog("threadrunsell%d",ticket);
    8. ticket--;
    9. pthread_mutex_unlock(&mutex);
    10. }
    11. else
    12. break;
    13. Sleep(1);
    14. //Usleep(10);
    15. returnNULL;
    16. }

    copy
      void*HelloWorld::th_go(true)
    1. pthread_mutex_lock(&mutex);
    2. if(ticket>0)
    3. CCLog("threadgosell%d",ticket);
    4. ticket--;
    5. pthread_mutex_unlock(&mutex);
    6. else
    7. break;
    8. returnNULL;
    9. copy
        void*HelloWorld::th_go(true)
      1. pthread_mutex_lock(&mutex);
      2. if(ticket>0)
      3. CCLog("threadgosell%d",ticket);
      4. ticket--;
      5. pthread_mutex_unlock(&mutex);
      6. else
      7. break;
      8. returnNULL;
      9. }


      mutex被锁定后,其他线程若再想锁定mutex的话,必须等待,当该线程释放了mutex之后,其他线程才能锁定mutex。Sleep()函数可以使得该线程休眠,单位是毫秒。下面是卖票的结果:

      copy
        nameiszhycheng,andageis23,sexismale
      1. deletedata
      2. threadrunsell100
      3. threadrunsell99
      4. threadgosell98
      5. threadgosell97
      6. threadrunsell96
      7. threadgosell95
      8. threadgosell94
      9. threadrunsell93
      10. threadgosell92
      11. threadrunsell91
      12. threadgosell90
      13. threadgosell89
      14. threadrunsell88
      15. threadgosell87
      16. threadrunsell86
      17. threadgosell85
      18. threadrunsell84
      19. threadgosell83
      20. threadrunsell82
      21. threadgosell81
      22. threadrunsell80
      23. threadgosell79
      24. threadrunsell78
      25. threadgosell77
      26. threadrunsell76
      27. threadgosell75
      28. threadrunsell74
      29. threadgosell73
      30. threadrunsell72
      31. threadgosell71
      32. threadrunsell70
      33. threadgosell69
      34. threadgosell68
      35. threadrunsell67
      36. threadgosell66
      37. threadrunsell65
      38. threadgosell64
      39. threadrunsell63
      40. threadgosell62
      41. threadrunsell61
      42. threadgosell60
      43. threadrunsell59
      44. threadgosell58
      45. threadrunsell57
      46. threadgosell56
      47. threadrunsell55
      48. threadgosell54
      49. threadrunsell53
      50. threadrunsell52
      51. threadgosell51
      52. threadrunsell50
      53. threadgosell49
      54. threadrunsell48
      55. threadgosell47
      56. threadrunsell46
      57. threadgosell45
      58. threadrunsell44
      59. threadrunsell43
      60. threadgosell42
      61. threadrunsell41
      62. threadrunsell40
      63. threadgosell39
      64. threadrunsell38
      65. threadrunsell37
      66. threadrunsell36
      67. threadrunsell35
      68. threadgosell34
      69. threadrunsell33
      70. threadrunsell32
      71. threadgosell31
      72. threadrunsell30
      73. threadrunsell29
      74. threadrunsell28
      75. threadrunsell27
      76. threadrunsell26
      77. threadrunsell25
      78. threadgosell24
      79. threadrunsell23
      80. threadgosell22
      81. threadgosell21
      82. threadrunsell20
      83. threadgosell19
      84. threadrunsell18
      85. threadrunsell17
      86. threadgosell16
      87. threadrunsell15
      88. threadgosell14
      89. threadgosell13
      90. threadrunsell12
      91. threadgosell11
      92. threadgosell10
      93. threadrunsell9
      94. threadgosell8
      95. threadrunsell7
      96. threadgosell6
      97. threadgosell5
      98. threadrunsell4
      99. threadgosell3
      100. threadrunsell2
      101. threadrunsell1
      copy
        nameiszhycheng,sexismale
      1. deletedata
      2. threadrunsell100
      3. threadrunsell99
      4. threadgosell98
      5. threadgosell97
      6. threadrunsell96
      7. threadgosell95
      8. threadgosell94
      9. threadrunsell93
      10. threadgosell92
      11. threadrunsell91
      12. threadgosell90
      13. threadgosell89
      14. threadrunsell88
      15. threadgosell87
      16. threadrunsell86
      17. threadgosell85
      18. threadrunsell84
      19. threadgosell83
      20. threadrunsell82
      21. threadgosell81
      22. threadrunsell80
      23. threadgosell79
      24. threadrunsell78
      25. threadgosell77
      26. threadrunsell76
      27. threadgosell75
      28. threadrunsell74
      29. threadgosell73
      30. threadrunsell72
      31. threadgosell71
      32. threadrunsell70
      33. threadgosell69
      34. threadgosell68
      35. threadrunsell67
      36. threadgosell66
      37. threadrunsell65
      38. threadgosell64
      39. threadrunsell63
      40. threadgosell62
      41. threadrunsell61
      42. threadgosell60
      43. threadrunsell59
      44. threadgosell58
      45. threadrunsell57
      46. threadgosell56
      47. threadrunsell55
      48. threadgosell54
      49. threadrunsell53
      50. threadrunsell52
      51. threadgosell51
      52. threadrunsell50
      53. threadgosell49
      54. threadrunsell48
      55. threadgosell47
      56. threadrunsell46
      57. threadgosell45
      58. threadrunsell44
      59. threadrunsell43
      60. threadgosell42
      61. threadrunsell41
      62. threadrunsell40
      63. threadgosell39
      64. threadrunsell38
      65. threadrunsell37
      66. threadrunsell36
      67. threadrunsell35
      68. threadgosell34
      69. threadrunsell33
      70. threadrunsell32
      71. threadgosell31
      72. threadrunsell30
      73. threadrunsell29
      74. threadrunsell28
      75. threadrunsell27
      76. threadrunsell26
      77. threadrunsell25
      78. threadgosell24
      79. threadrunsell23
      80. threadgosell22
      81. threadgosell21
      82. threadrunsell20
      83. threadgosell19
      84. threadrunsell18
      85. threadrunsell17
      86. threadgosell16
      87. threadrunsell15
      88. threadgosell14
      89. threadgosell13
      90. threadrunsell12
      91. threadgosell11
      92. threadgosell10
      93. threadrunsell9
      94. threadgosell8
      95. threadrunsell7
      96. threadgosell6
      97. threadgosell5
      98. threadrunsell4
      99. threadgosell3
      100. threadrunsell2
      101. threadrunsell1


      可以看到,这个打印结果正确无误。如果不加mutex会是什么样的结果呢,我将线程同步的mutex注释掉,输出的结果为:

      copy
        threadrunsell98
      1. threadrunsell94
      2. threadgosell94
      3. threadrunsell92
      4. threadrunsell89
      5. threadgosell88
      6. threadrunsell87
      7. threadgosell86
      8. threadgosell84
      9. threadrunsell83
      10. threadgosell82
      11. threadrunsell81
      12. threadgosell80
      13. threadrunsell79
      14. threadrunsell75
      15. threadgosell74
      16. threadrunsell73
      17. threadgosell72
      18. threadrunsell71
      19. threadgosell70
      20. threadrunsell68
      21. threadgosell67
      22. threadgosell63
      23. threadrunsell62
      24. threadgosell61
      25. threadrunsell60
      26. threadrunsell58
      27. threadrunsell56
      28. threadrunsell54
      29. threadgosell52
      30. threadrunsell52
      31. threadgosell50
      32. threadrunsell50
      33. threadgosell49
      34. threadrunsell47
      35. threadgosell47
      36. threadrunsell45
      37. threadrunsell43threadgosell43
      38. threadgosell41
      39. threadrunsell39
      40. threadgosell37
      41. threadgosell35
      42. threadrunsell35
      43. threadgosell33threadrunsell33
      44. threadgosell31threadrunsell31
      45. threadgosell29
      46. threadrunsell29
      47. threadgosell27
      48. threadrunsell27
      49. threadgosell25
      50. threadrunsell25
      51. threadgosell23
      52. threadrunsell21
      53. threadgosell21
      54. threadrunsell19
      55. threadgosell17
      56. threadgosell15
      57. threadrunsell15
      58. threadrunsell13
      59. threadgosell13
      60. threadrunsell11threadgosell11
      61. threadgosell9
      62. threadrunsell9
      63. threadgosell7
      64. threadgosell5threadrunsell5
      65. threadrunsell3
      66. threadgosell1
      67. copy
          threadrunsell98
        1. threadrunsell94
        2. threadgosell94
        3. threadrunsell92
        4. threadrunsell89
        5. threadgosell88
        6. threadrunsell87
        7. threadgosell86
        8. threadgosell84
        9. threadrunsell83
        10. threadgosell82
        11. threadrunsell81
        12. threadgosell80
        13. threadrunsell79
        14. threadrunsell75
        15. threadgosell74
        16. threadrunsell73
        17. threadgosell72
        18. threadrunsell71
        19. threadgosell70
        20. threadrunsell68
        21. threadgosell67
        22. threadgosell63
        23. threadrunsell62
        24. threadgosell61
        25. threadrunsell60
        26. threadrunsell58
        27. threadrunsell56
        28. threadrunsell54
        29. threadgosell52
        30. threadrunsell52
        31. threadgosell50
        32. threadrunsell50
        33. threadgosell49
        34. threadrunsell47
        35. threadgosell47
        36. threadrunsell45
        37. threadrunsell43threadgosell43
        38. threadgosell41
        39. threadrunsell39
        40. threadgosell37
        41. threadgosell35
        42. threadrunsell35
        43. threadgosell33threadrunsell33
        44. threadgosell31threadrunsell31
        45. threadgosell29
        46. threadrunsell29
        47. threadgosell27
        48. threadrunsell27
        49. threadgosell25
        50. threadrunsell25
        51. threadgosell23
        52. threadrunsell21
        53. threadgosell21
        54. threadrunsell19
        55. threadgosell17
        56. threadgosell15
        57. threadrunsell15
        58. threadrunsell13
        59. threadgosell13
        60. threadrunsell11threadgosell11
        61. threadgosell9
        62. threadrunsell9
        63. threadgosell7
        64. threadgosell5threadrunsell5
        65. threadrunsell3
        66. threadgosell1
        67. threadrunsell1


        可以看到,有的票卖了两次,有的票就没卖。

        4.注意

        1.Sleep()函数是使得线程休眠的函数,这个函数不跨平台,仅仅在windows上能用,其他平台使用usleep。

        2.在非主线程中不能使用cocos2d-x管理内存的CCObject::retain(),CCObject::release()CCObject::autorelease(),因为CCAutoreleasePool不是线程安全的,OPENGL的上下文也不是线程安全的,所以不要再非主线程中使用cocos2d-x的API和UI操作。



        cocos2dx内存管理与多线程问题:

        Cocos2d-x的内存管理采用Objective-C的机制,大喜过望。因为只要坚持Objective-C的原则“谁创建谁释放,谁备份谁释放”的原则即可确保内存使用不易出现Bug。
        但是因为本身开放的游戏需要使用到多线程技术,导致测试的时候总是莫名其妙的导致空指针错误。而且是随机出现,纠结了2天无果后,开始怀疑Cocos2d-X的内存本身管理可能存在问题。怀着这样的想法,
        一步一步的调试,发现经常出现指针异常的变量总是在调用autorelease后一会就莫名其妙再使用的时候就抛异常。狠下心,在它的析构函数里面断点+Log输出信息。发现对象被释放了。一时也很迷糊,因为对象只是

        autorelease,并没有真正释放,是谁导致它释放的?


        然后就去看了CCAutoreleasePool的源码,发现存在Cocos2d-X的内存管理在多线程的情况下存在如下问题

        如图:thread 1和thread 2是独立的两个线程,它们之间存在CPU分配的交叉集,我们在time 1的时候push一个autorelease的自动释放池,在该线程的末尾,即time 3的时候pop它。同理在thread 2的线程里面,在time 2的时候push一个自动释放池,在time 4的时候释放它,即Pop.
        此时我们假设在thread 2分配得到CPU的时候有一个对象obj自动释放,即obj-autorelease().那么在time 3的时候会发生是么事情呢?
        答案很简单,就是obj在time 3的时候就被释放了,而我们期望它在time 4的时候才释放。所以就导致我上面说的,在多线程下面,cocos2d-x的autorelease变量会发生莫名其妙的指针异常。
        解决办法:在PoolManager给每个线程根据pthread_t的线程id生成一个CCArray的stack的嵌套管理自动释放池。源码如下
        所以我在Push的时候根据当前线程的pthread_t的线程id生成一个CCArray的stack来存储该线程对应的Autoreleasepool的嵌套对象
        源码如下

        1

        2

        3

        4

        5

        6

        7

        8

        9

        10

        11

        12

        13

        14

        15

        16

        17

        18

        19

        20

        21

        22

        23

        24

        25

        26

        27

        28

        29

        30

        31

        32

        33

        34

        35

        36

        37

        38

        39

        40

        41

        42

        43

        44

        45

        46

        47

        48

        49

        50

        51

        52

        53

        54

        55

        56

        57

        58

        59

        60

        61

        62

        63

        64

        65

        66

        67

        68

        69

        70

        71

        72

        73

        74

        75

        76

        77

        78

        79

        80

        81

        82

        83

        84

        85

        86

        87

        88

        89

        90

        91

        92

        93

        94

        95

        96

        97

        98

        99

        100

        101

        102

        103

        104

        105

        106

        107

        108

        109

        110

        111

        112

        113

        114

        115

        116

        117

        118

        119

        120

        121

        122

        123

        124

        125

        126

        127

        128

        129

        130

        131

        132

        133

        134

        135

        136

        137

        138

        139

        140

        141

        142

        143

        144

        145

        146

        147

        148

        149

        150

        151

        152

        153

        154

        155

        156

        157

        158

        159

        160

        161

        162

        163

        164

        165

        166

        167

        168

        169

        170

        171

        172

        173

        174

        175

        176

        177

        178

        179

        180

        181

        182

        183

        184

        185

        186

        187

        188

        189

        190

        191

        192

        193

        194

        195

        196

        197

        198

        199

        200

        201

        202

        203

        204

        205

        206

        207

        208

        209

        210

        //--------------------------------------------------------------------

        //

        // CCPoolManager

        //

        //--------------------------------------------------------------------


        /////【diff - begin】- by layne//////


        CCPoolManager* CCPoolManager::sharedPoolManager()

        {

        if (s_pPoolManager == NULL)

        {

        s_pPoolManager = new CCPoolManager();

        }

        return s_pPoolManager;

        }


        void CCPoolManager::purgePoolManager()

        {

        CC_SAFE_DELETE(s_pPoolManager);

        }


        CCPoolManager::CCPoolManager()

        {

        // m_pReleasePoolStack = new CCArray();

        // m_pReleasePoolStack->init();

        // m_pCurReleasePool = 0;


        m_pReleasePoolMultiStack = new CCDictionary();

        }


        CCPoolManager::~CCPoolManager()

        {


        // finalize();


        // // we only release the last autorelease pool here

        // m_pCurReleasePool = 0;

        // m_pReleasePoolStack->removeObjectAtIndex(0);

        //

        // CC_SAFE_DELETE(m_pReleasePoolStack);


        finalize();


        CC_SAFE_DELETE(m_pReleasePoolMultiStack);

        }


        void CCPoolManager::finalize()

        {

        if(m_pReleasePoolMultiStack->count() > 0)

        {

        //CCAutoreleasePool* pReleasePool;

        CCObject* pkey = NULL;

        CCARRAY_FOREACH(m_pReleasePoolMultiStack->allKeys(),pkey)

        {

        if(!pkey)

        break;

        CCInteger *key = (CCInteger*)pkey;

        CCArray *poolStack = (CCArray *)m_pReleasePoolMultiStack->objectForKey(key->getValue());

        CCObject* pObj = NULL;

        CCARRAY_FOREACH(poolStack,pObj)

        {

        if(!pObj)

        break;

        CCAutoreleasePool* pPool = (CCAutoreleasePool*)pObj;

        pPool->clear();

        }

        }

        }

        }


        void CCPoolManager::push()

        {

        // CCAutoreleasePool* pPool = new CCAutoreleasePool(); //ref = 1

        // m_pCurReleasePool = pPool;

        //

        // m_pReleasePoolStack->addObject(pPool); //ref = 2

        //

        // pPool->release(); //ref = 1


        pthread_mutex_lock(&m_mutex);


        CCArray* pCurReleasePoolStack = getCurReleasePoolStack();

        CCAutoreleasePool* pPool = new CCAutoreleasePool(); //ref = 1

        pCurReleasePoolStack->addObject(pPool); //ref = 2

        pPool->release(); //ref = 1


        pthread_mutex_unlock(&m_mutex);

        }


        void CCPoolManager::pop()

        {

        // if (! m_pCurReleasePool)

        // {

        // return;

        // }

        //

        // int nCount = m_pReleasePoolStack->count();

        //

        // m_pCurReleasePool->clear();

        //

        // if(nCount > 1)

        // {

        // m_pReleasePoolStack->removeObjectAtIndex(nCount-1);

        //

        // // if(nCount > 1)

        // // {

        // // m_pCurReleasePool = m_pReleasePoolStack->objectAtIndex(nCount - 2);

        // // return;

        // // }

        // m_pCurReleasePool = (CCAutoreleasePool*)m_pReleasePoolStack->objectAtIndex(nCount - 2);

        // }

        //

        // /*m_pCurReleasePool = NULL;*/


        pthread_mutex_lock(&m_mutex);


        CCArray* pCurReleasePoolStack = getCurReleasePoolStack();

        CCAutoreleasePool* pCurReleasePool = getCurReleasePool();

        if (pCurReleasePoolStack && pCurReleasePool)

        {

        int nCount = pCurReleasePoolStack->count();


        pCurReleasePool->clear();


        if(nCount > 1)

        {

        pCurReleasePoolStack->removeObject(pCurReleasePool);

        }

        }


        pthread_mutex_unlock(&m_mutex);

        }


        void CCPoolManager::removeObject(CCObject* pObject)

        {

        // CCAssert(m_pCurReleasePool,"current auto release pool should not be null");

        //

        // m_pCurReleasePool->removeObject(pObject);


        pthread_mutex_lock(&m_mutex);

        CCAutoreleasePool* pCurReleasePool = getCurReleasePool();

        CCAssert(pCurReleasePool,"current auto release pool should not be null");


        pCurReleasePool->removeObject(pObject);

        pthread_mutex_unlock(&m_mutex);

        }


        void CCPoolManager::addObject(CCObject* pObject)

        {

        // getCurReleasePool()->addObject(pObject);


        pthread_mutex_lock(&m_mutex);

        CCAutoreleasePool* pCurReleasePool = getCurReleasePool(true);

        CCAssert(pCurReleasePool,"current auto release pool should not be null");


        pCurReleasePool->addObject(pObject);

        pthread_mutex_unlock(&m_mutex);

        }


        CCArray* CCPoolManager::getCurReleasePoolStack()

        {

        CCArray* pPoolStack = NULL;

        pthread_t tid = pthread_self();

        if(m_pReleasePoolMultiStack->count() > 0)

        {

        pPoolStack = (CCArray*)m_pReleasePoolMultiStack->objectForKey((int)tid);

        }


        if (!pPoolStack) {

        pPoolStack = new CCArray();

        m_pReleasePoolMultiStack->setObject(pPoolStack,(int)tid);

        pPoolStack->release();

        }


        return pPoolStack;

        }


        CCAutoreleasePool* CCPoolManager::getCurReleasePool(bool autoCreate)

        {

        // if(!m_pCurReleasePool)

        // {

        // push();

        // }

        //

        // CCAssert(m_pCurReleasePool,"current auto release pool should not be null");

        //

        // return m_pCurReleasePool;


        CCAutoreleasePool* pReleasePool = NULL;



        CCArray* pPoolStack = getCurReleasePoolStack();

        if(pPoolStack->count() > 0)

        {

        pReleasePool = (CCAutoreleasePool*)pPoolStack->lastObject();

        }


        if (!pReleasePool && autoCreate) {

        CCAutoreleasePool* pPool = new CCAutoreleasePool(); //ref = 1

        pPoolStack->addObject(pPool); //ref = 2

        pPool->release(); //ref = 1


        pReleasePool = pPool;

        }


        return pReleasePool;

        }


        /////【diff - end】- by layne//////



        代码下载地址:https://github.com/kaitiren/pthread-test-for-cocos2dx

        (编辑:李大同)

        【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读