2dx设备上log cocos_cocos2dx log - CSDN
  • 一直使用vs2010开发cocos2dx,查看cocos2dxlog也一直使用CCLog来打印到vs2010的输出控制台,同时也可以将log输出到命令行窗口。  log输出方法一: 使用CCLog输出到vs控制台,当然了,这也可以跨平台输出log...

    一直使用vs2010开发cocos2dx,查看cocos2dx的log也一直使用CCLog来打印到vs2010的输出控制台,同时也可以将log输出到命令行窗口。 

    log输出方法一:

    使用CCLog输出到vs控制台,当然了,这也可以跨平台输出log。 

    如: 

    CCLog("error buffer:%s" ,response->getErrorBuffer()); 

    log输出方法二: 

    在打印前,加入以下代码: 

    AllocConsole();

     freopen("CONIN$", "r", stdin);

     freopen("CONOUT$", "w", stdout);

     freopen("CONOUT$", "w", stderr);

    那么无论是CCLog,还是sprinf,可以立刻输出到命令行窗口了,非常方便查看。

    展开全文
  • 一直使用vs2010开发cocos2dx,查看cocos2dxlog也一直使用CCLog来打印到vs2010的输出控制台,同时也可以将log输出到命令行窗口。 log输出方法一: 使用CCLog输出到vs控制台,当然了,这也可以跨平台输出loglog...

    一直使用vs2010开发cocos2dx,查看cocos2dx的log也一直使用CCLog来打印到vs2010的输出控制台,同时也可以将log输出到命令行窗口

    log输出方法一:

    使用CCLog输出到vs控制台,当然了,这也可以跨平台输出log。

    如:

    CCLog("error buffer:%s" ,response->getErrorBuffer());

    log输出方法二:

    在打印前,加入以下代码:

            AllocConsole();
    	freopen("CONIN$", "r", stdin);
    	freopen("CONOUT$", "w", stdout);
    	freopen("CONOUT$", "w", stderr);
    那么无论是CCLog,还是sprinf,可以立刻输出到命令行窗口了,非常方便查看。

    展开全文
  • Sample Code CCLOG ("Characters: %c %c \n", 'a', 65); CCLOG ("Decimals: %d %ld\n", 1977, 650000L); CCLOG ("Preceding with blanks: %10d \n", 1977); CCLOG ("Preceding with zeros: %010d \n", 1977);

    Sample Code

    CCLOG ("Characters: %c %c \n", 'a', 65);
    CCLOG ("Decimals: %d %ld\n", 1977, 650000L);
    CCLOG ("Preceding with blanks: %10d \n", 1977);
    CCLOG ("Preceding with zeros: %010d \n", 1977);
    CCLOG ("Some different radixes: %d %x %o %#x %#o \n", 100, 100, 100, 100, 100);
    CCLOG ("floats: %4.2f %+.0e %E \n", 3.1416, 3.1416, 3.1416);
    CCLOG ("Width trick: %*d \n", 5, 10);
    CCLOG ("%s \n", "A string");

    PS: 输出64位的要用"%lld"

    Output

    Cocos2d: Characters: a A 
    Cocos2d: Decimals: 1977 650000
    Cocos2d: Preceding with blanks: 1977 
    Cocos2d: Preceding with zeros: 0000001977 
    Cocos2d: Some different radixes: 100 64 144 0x64 0144 
    Cocos2d: floats: 3.14 +3e+00 3.141600E+00 
    Cocos2d: Width trick: 10 
    Cocos2d: A string

    举例说明:


     

    12、cocos2d-x使用CCLOG实现log输出 - 呵呵 加油 - 呵呵 加油

     

    12、cocos2d-x使用CCLOG实现log输出 - 呵呵 加油 - 呵呵 加油


    展开全文
  • cocos2d-x引擎在内部实现了一个庞大的主循环,每帧之间更新界面,如果耗时的操作放到了主线程中,游戏的界面就会卡,这是不能容忍的,游戏最基本的条件就是流畅性,这就是为什么游戏开发选择C++的原因。另外现在双核...

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

    1.环境搭建

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


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


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

    2.多线程的使用

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

    1. PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid,//线程的标示   
    2.                             const pthread_attr_t * attr,      //创建线程的参数   
    3.                             void *(*start) (void *),          //入口函数的指针   
    4.                             void *arg);                       //传递给线程的数据  
    1. PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid,//线程的标示  
    2.                             const pthread_attr_t * attr,      //创建线程的参数  
    3.                             void *(*start) (void *),          //入口函数的指针  
    4.                             void *arg);                       //传递给线程的数据  

    在HelloWorldScene.h文件中

    1. pthread_t pidrun,pidgo;  
    2. static void* th_run(void *r);  
    3. static void* th_go(void *r);  
    1. pthread_t pidrun,pidgo;  
    2. static void* th_run(void *r);  
    3. static void* th_go(void *r);  
    定义了两个函数和两个线程的标识。

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

    1. #pragma once   
    2. #include <string>   
    3. class Student  
    4. {  
    5. public:  
    6.     Student(void);  
    7.     Student(std::string name,int age,std::string sex);  
    8.     ~Student(void);  
    9.   
    10.     std::string name;  
    11.     int age;  
    12.     std::string sex;  
    13.   
    14. };  
    1. #pragma once  
    2. #include <string>  
    3. class Student  
    4. {  
    5. public:  
    6.     Student(void);  
    7.     Student(std::string name,int age,std::string sex);  
    8.     ~Student(void);  
    9.   
    10.     std::string name;  
    11.     int age;  
    12.     std::string sex;  
    13.   
    14. };  

    源文件如下

    1. #include "Student.h"   
    2. #include "cocos2d.h"   
    3.   
    4. Student::Student(void)  
    5. {  
    6. }  
    7.   
    8.   
    9. Student::~Student(void)  
    10. {  
    11.     cocos2d::CCLog("delete data");  
    12. }  
    13. Student::Student(std::string name,int age,std::string sex)  
    14. {  
    15.     this->name=name;  
    16.     this->age=age;  
    17.     this->sex=sex;  
    18. }  
    1. #include "Student.h"  
    2. #include "cocos2d.h"  
    3.   
    4. Student::Student(void)  
    5. {  
    6. }  
    7.   
    8.   
    9. Student::~Student(void)  
    10. {  
    11.     cocos2d::CCLog("delete data");  
    12. }  
    13. Student::Student(std::string name,int age,std::string sex)  
    14. {  
    15.     this->name=name;  
    16.     this->age=age;  
    17.     this->sex=sex;  
    18. }  
    在退出菜单的回调函数中启动两个线程:

    1. void HelloWorld::menuCloseCallback(CCObject* pSender)  
    2. {  
    3.      
    4.     Student *temp=new Student(std::string("zhycheng"),23,std::string("male"));  
    5.     pthread_mutex_init(&mutex,NULL);  
    6.     pthread_create(&pidrun,NULL,th_run,temp);//启动线程   
    7.     pthread_create(&pidgo,NULL,th_go,0);  
    8.   
    9. }  
    1. void HelloWorld::menuCloseCallback(CCObject* pSender)  
    2. {  
    3.      
    4.     Student *temp=new Student(std::string("zhycheng"),23,std::string("male"));  
    5.     pthread_mutex_init(&mutex,NULL);  
    6.     pthread_create(&pidrun,NULL,th_run,temp);//启动线程  
    7.     pthread_create(&pidgo,NULL,th_go,0);  
    8.   
    9. }  

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

    1.        Student *s=(Student*)(r);  
    2. CCLog("name is %s,and age is %d,sex is %s",s->name.c_str(),s->age,s->sex.c_str());  
    3. delete s;  
    1.        Student *s=(Student*)(r);  
    2. CCLog("name is %s,and age is %d,sex is %s",s->name.c_str(),s->age,s->sex.c_str());  
    3. delete s;  

    3.线程同步

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

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

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

    1. void* HelloWorld::th_run(void *r)  
    2. {  
    3.       
    4.     Student *s=(Student*)(r);  
    5.     CCLog("name is %s,and age is %d,sex is %s",s->name.c_str(),s->age,s->sex.c_str());  
    6.     delete s;  
    7.     while(true)  
    8.     {  
    9.         pthread_mutex_lock(&mutex);  
    10.         if(ticket>0)  
    11.         {  
    12.         CCLog("thread run sell %d",ticket);  
    13.         ticket--;  
    14.         pthread_mutex_unlock(&mutex);  
    15.         }  
    16.         else  
    17.         {  
    18.             pthread_mutex_unlock(&mutex);  
    19.             break;    
    20.         }  
    21.       
    22.         Sleep(1);  
    23.         //Usleep(10);   
    24.     }  
    25.   
    26.     return NULL;  
    27. }  
    1. void* HelloWorld::th_run(void *r)  
    2. {  
    3.       
    4.     Student *s=(Student*)(r);  
    5.     CCLog("name is %s,and age is %d,sex is %s",s->name.c_str(),s->age,s->sex.c_str());  
    6.     delete s;  
    7.     while(true)  
    8.     {  
    9.         pthread_mutex_lock(&mutex);  
    10.         if(ticket>0)  
    11.         {  
    12.         CCLog("thread run sell %d",ticket);  
    13.         ticket--;  
    14.         pthread_mutex_unlock(&mutex);  
    15.         }  
    16.         else  
    17.         {  
    18.             pthread_mutex_unlock(&mutex);  
    19.             break;    
    20.         }  
    21.       
    22.         Sleep(1);  
    23.         //Usleep(10);  
    24.     }  
    25.   
    26.     return NULL;  
    27. }  

    1. void* HelloWorld::th_go(void *r)  
    2. {  
    3.       
    4.     while(true)  
    5.     {  
    6.         pthread_mutex_lock(&mutex);  
    7.         if(ticket>0)  
    8.         {  
    9.         CCLog("thread go sell %d",ticket);  
    10.         ticket--;  
    11.         pthread_mutex_unlock(&mutex);  
    12.         }  
    13.         else  
    14.         {  
    15.             pthread_mutex_unlock(&mutex);  
    16.             break;  
    17.               
    18.         }  
    19.           
    20.         Sleep(1);  
    21.           
    22.     }  
    23.     return NULL;  
    24. }  
    1. void* HelloWorld::th_go(void *r)  
    2. {  
    3.       
    4.     while(true)  
    5.     {  
    6.         pthread_mutex_lock(&mutex);  
    7.         if(ticket>0)  
    8.         {  
    9.         CCLog("thread go sell %d",ticket);  
    10.         ticket--;  
    11.         pthread_mutex_unlock(&mutex);  
    12.         }  
    13.         else  
    14.         {  
    15.             pthread_mutex_unlock(&mutex);  
    16.             break;  
    17.               
    18.         }  
    19.           
    20.         Sleep(1);  
    21.           
    22.     }  
    23.     return NULL;  
    24. }  


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

    1. name is zhycheng,and age is 23,sex is male  
    2. delete data  
    3. thread run sell 100  
    4. thread run sell 99  
    5. thread go sell 98  
    6. thread go sell 97  
    7. thread run sell 96  
    8. thread go sell 95  
    9. thread go sell 94  
    10. thread run sell 93  
    11. thread go sell 92  
    12. thread run sell 91  
    13. thread go sell 90  
    14. thread go sell 89  
    15. thread run sell 88  
    16. thread go sell 87  
    17. thread run sell 86  
    18. thread go sell 85  
    19. thread run sell 84  
    20. thread go sell 83  
    21. thread run sell 82  
    22. thread go sell 81  
    23. thread run sell 80  
    24. thread go sell 79  
    25. thread run sell 78  
    26. thread go sell 77  
    27. thread run sell 76  
    28. thread go sell 75  
    29. thread run sell 74  
    30. thread go sell 73  
    31. thread run sell 72  
    32. thread go sell 71  
    33. thread run sell 70  
    34. thread go sell 69  
    35. thread go sell 68  
    36. thread run sell 67  
    37. thread go sell 66  
    38. thread run sell 65  
    39. thread go sell 64  
    40. thread run sell 63  
    41. thread go sell 62  
    42. thread run sell 61  
    43. thread go sell 60  
    44. thread run sell 59  
    45. thread go sell 58  
    46. thread run sell 57  
    47. thread go sell 56  
    48. thread run sell 55  
    49. thread go sell 54  
    50. thread run sell 53  
    51. thread run sell 52  
    52. thread go sell 51  
    53. thread run sell 50  
    54. thread go sell 49  
    55. thread run sell 48  
    56. thread go sell 47  
    57. thread run sell 46  
    58. thread go sell 45  
    59. thread run sell 44  
    60. thread run sell 43  
    61. thread go sell 42  
    62. thread run sell 41  
    63. thread run sell 40  
    64. thread go sell 39  
    65. thread run sell 38  
    66. thread run sell 37  
    67. thread run sell 36  
    68. thread run sell 35  
    69. thread go sell 34  
    70. thread run sell 33  
    71. thread run sell 32  
    72. thread go sell 31  
    73. thread run sell 30  
    74. thread run sell 29  
    75. thread run sell 28  
    76. thread run sell 27  
    77. thread run sell 26  
    78. thread run sell 25  
    79. thread go sell 24  
    80. thread run sell 23  
    81. thread go sell 22  
    82. thread go sell 21  
    83. thread run sell 20  
    84. thread go sell 19  
    85. thread run sell 18  
    86. thread run sell 17  
    87. thread go sell 16  
    88. thread run sell 15  
    89. thread go sell 14  
    90. thread go sell 13  
    91. thread run sell 12  
    92. thread go sell 11  
    93. thread go sell 10  
    94. thread run sell 9  
    95. thread go sell 8  
    96. thread run sell 7  
    97. thread go sell 6  
    98. thread go sell 5  
    99. thread run sell 4  
    100. thread go sell 3  
    101. thread run sell 2  
    102. thread run sell 1  
    1. name is zhycheng,and age is 23,sex is male  
    2. delete data  
    3. thread run sell 100  
    4. thread run sell 99  
    5. thread go sell 98  
    6. thread go sell 97  
    7. thread run sell 96  
    8. thread go sell 95  
    9. thread go sell 94  
    10. thread run sell 93  
    11. thread go sell 92  
    12. thread run sell 91  
    13. thread go sell 90  
    14. thread go sell 89  
    15. thread run sell 88  
    16. thread go sell 87  
    17. thread run sell 86  
    18. thread go sell 85  
    19. thread run sell 84  
    20. thread go sell 83  
    21. thread run sell 82  
    22. thread go sell 81  
    23. thread run sell 80  
    24. thread go sell 79  
    25. thread run sell 78  
    26. thread go sell 77  
    27. thread run sell 76  
    28. thread go sell 75  
    29. thread run sell 74  
    30. thread go sell 73  
    31. thread run sell 72  
    32. thread go sell 71  
    33. thread run sell 70  
    34. thread go sell 69  
    35. thread go sell 68  
    36. thread run sell 67  
    37. thread go sell 66  
    38. thread run sell 65  
    39. thread go sell 64  
    40. thread run sell 63  
    41. thread go sell 62  
    42. thread run sell 61  
    43. thread go sell 60  
    44. thread run sell 59  
    45. thread go sell 58  
    46. thread run sell 57  
    47. thread go sell 56  
    48. thread run sell 55  
    49. thread go sell 54  
    50. thread run sell 53  
    51. thread run sell 52  
    52. thread go sell 51  
    53. thread run sell 50  
    54. thread go sell 49  
    55. thread run sell 48  
    56. thread go sell 47  
    57. thread run sell 46  
    58. thread go sell 45  
    59. thread run sell 44  
    60. thread run sell 43  
    61. thread go sell 42  
    62. thread run sell 41  
    63. thread run sell 40  
    64. thread go sell 39  
    65. thread run sell 38  
    66. thread run sell 37  
    67. thread run sell 36  
    68. thread run sell 35  
    69. thread go sell 34  
    70. thread run sell 33  
    71. thread run sell 32  
    72. thread go sell 31  
    73. thread run sell 30  
    74. thread run sell 29  
    75. thread run sell 28  
    76. thread run sell 27  
    77. thread run sell 26  
    78. thread run sell 25  
    79. thread go sell 24  
    80. thread run sell 23  
    81. thread go sell 22  
    82. thread go sell 21  
    83. thread run sell 20  
    84. thread go sell 19  
    85. thread run sell 18  
    86. thread run sell 17  
    87. thread go sell 16  
    88. thread run sell 15  
    89. thread go sell 14  
    90. thread go sell 13  
    91. thread run sell 12  
    92. thread go sell 11  
    93. thread go sell 10  
    94. thread run sell 9  
    95. thread go sell 8  
    96. thread run sell 7  
    97. thread go sell 6  
    98. thread go sell 5  
    99. thread run sell 4  
    100. thread go sell 3  
    101. thread run sell 2  
    102. thread run sell 1  


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

    1. name is zhycheng,and age is 23,sex is male  
    2. delete data  
    3. thread run sell 100  
    4. thread run sell 99  
    5. thread run sell 98  
    6. thread go sell 97  
    7. thread run sell 96  
    8. thread go sell 95  
    9. thread run sell 94  
    10. thread go sell 94  
    11. thread run sell 92  
    12. thread run sell 91  
    13. thread go sell 90  
    14. thread run sell 89  
    15. thread go sell 88  
    16. thread run sell 87  
    17. thread run sell 86  
    18. thread go sell 86  
    19. thread go sell 84  
    20. thread run sell 83  
    21. thread go sell 82  
    22. thread run sell 81  
    23. thread go sell 80  
    24. thread run sell 79  
    25. thread run sell 78  
    26. thread go sell 77  
    27. thread run sell 76  
    28. thread run sell 75  
    29. thread go sell 74  
    30. thread run sell 73  
    31. thread go sell 72  
    32. thread run sell 71  
    33. thread go sell 70  
    34. thread go sell 69  
    35. thread run sell 68  
    36. thread go sell 67  
    37. thread go sell 66  
    38. thread run sell 65  
    39. thread go sell 64  
    40. thread go sell 63  
    41. thread run sell 62  
    42. thread go sell 61  
    43. thread run sell 60  
    44. thread run sell 59  
    45. thread run sell 58  
    46. thread run sell 57  
    47. thread run sell 56  
    48. thread run sell 55  
    49. thread go sell 54  
    50. thread run sell 54  
    51. thread go sell 52  
    52. thread run sell 52  
    53. thread go sell 50  
    54. thread run sell 50  
    55. thread go sell 49  
    56. thread run sell 47  
    57. thread go sell 47  
    58. thread go sell 45  
    59. thread run sell 45  
    60. thread run sell 43thread go sell 43  
    61.   
    62. thread run sell 41  
    63. thread go sell 41  
    64. thread go sell 39  
    65. thread run sell 39  
    66. thread run sell 37  
    67. thread go sell 37  
    68. thread go sell 35  
    69. thread run sell 35  
    70. thread go sell 33thread run sell 33  
    71.   
    72. thread go sell 31thread run sell 31  
    73.   
    74. thread go sell 29  
    75. thread run sell 29  
    76. thread go sell 27  
    77. thread run sell 27  
    78. thread go sell 25  
    79. thread run sell 25  
    80. thread run sell 23  
    81. thread go sell 23  
    82. thread run sell 21  
    83. thread go sell 21  
    84. thread go sell 19  
    85. thread run sell 19  
    86. thread run sell 17  
    87. thread go sell 17  
    88. thread go sell 15  
    89. thread run sell 15  
    90. thread run sell 13  
    91. thread go sell 13  
    92. thread run sell 11thread go sell 11  
    93.   
    94. thread go sell 9  
    95. thread run sell 9  
    96. thread run sell 7  
    97. thread go sell 7  
    98. thread go sell 5thread run sell 5  
    99.   
    100. thread go sell 3  
    101. thread run sell 3  
    102. thread go sell 1  
    103. thread run sell 1  
    1. name is zhycheng,and age is 23,sex is male  
    2. delete data  
    3. thread run sell 100  
    4. thread run sell 99  
    5. thread run sell 98  
    6. thread go sell 97  
    7. thread run sell 96  
    8. thread go sell 95  
    9. thread run sell 94  
    10. thread go sell 94  
    11. thread run sell 92  
    12. thread run sell 91  
    13. thread go sell 90  
    14. thread run sell 89  
    15. thread go sell 88  
    16. thread run sell 87  
    17. thread run sell 86  
    18. thread go sell 86  
    19. thread go sell 84  
    20. thread run sell 83  
    21. thread go sell 82  
    22. thread run sell 81  
    23. thread go sell 80  
    24. thread run sell 79  
    25. thread run sell 78  
    26. thread go sell 77  
    27. thread run sell 76  
    28. thread run sell 75  
    29. thread go sell 74  
    30. thread run sell 73  
    31. thread go sell 72  
    32. thread run sell 71  
    33. thread go sell 70  
    34. thread go sell 69  
    35. thread run sell 68  
    36. thread go sell 67  
    37. thread go sell 66  
    38. thread run sell 65  
    39. thread go sell 64  
    40. thread go sell 63  
    41. thread run sell 62  
    42. thread go sell 61  
    43. thread run sell 60  
    44. thread run sell 59  
    45. thread run sell 58  
    46. thread run sell 57  
    47. thread run sell 56  
    48. thread run sell 55  
    49. thread go sell 54  
    50. thread run sell 54  
    51. thread go sell 52  
    52. thread run sell 52  
    53. thread go sell 50  
    54. thread run sell 50  
    55. thread go sell 49  
    56. thread run sell 47  
    57. thread go sell 47  
    58. thread go sell 45  
    59. thread run sell 45  
    60. thread run sell 43thread go sell 43  
    61.   
    62. thread run sell 41  
    63. thread go sell 41  
    64. thread go sell 39  
    65. thread run sell 39  
    66. thread run sell 37  
    67. thread go sell 37  
    68. thread go sell 35  
    69. thread run sell 35  
    70. thread go sell 33thread run sell 33  
    71.   
    72. thread go sell 31thread run sell 31  
    73.   
    74. thread go sell 29  
    75. thread run sell 29  
    76. thread go sell 27  
    77. thread run sell 27  
    78. thread go sell 25  
    79. thread run sell 25  
    80. thread run sell 23  
    81. thread go sell 23  
    82. thread run sell 21  
    83. thread go sell 21  
    84. thread go sell 19  
    85. thread run sell 19  
    86. thread run sell 17  
    87. thread go sell 17  
    88. thread go sell 15  
    89. thread run sell 15  
    90. thread run sell 13  
    91. thread go sell 13  
    92. thread run sell 11thread go sell 11  
    93.   
    94. thread go sell 9  
    95. thread run sell 9  
    96. thread run sell 7  
    97. thread go sell 7  
    98. thread go sell 5thread run sell 5  
    99.   
    100. thread go sell 3  
    101. thread run sell 3  
    102. thread go sell 1  
    103. thread run sell 1  


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

    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



    展开全文
  • cocos2dx三种定时器的使用以及停止schedule,scheduleUpdate,scheduleOnce
  • 用eclipse编译通过生成了.so 然后用真机通过USB进行调试 debug as [armeabi] Install : libcocos2dcpp.so => libs/armeabi/...我在Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit这个入口函数的第一行加
  • Cocos2dx入门

    2019-04-18 22:36:19
    一.Cocos2d-x引擎特性 现代化的 C++ API 立足于 C++ 同时支持 JavaScript/Lua 作为开发语言 可以跨平台部署, 支持 iOS、Android、Windows、macOS 和 Linux 可以在 PC 端完成游戏的测试,最终发布到移动端 完善的游戏...
  • 联网游戏开发中,经常遇到http编程,接下来就分三次...如果要使用cocos2dx的CCHttpClient来进行网络访问,则需要引入cocos2dx的相关库,详细步骤如下: 右键单击项目->属性->c/c++->常规,在右边的附件包含目录中添加co
  • 官方发布说明: https://github.com/fusijie/Cocos2dx-Release-Note/blob/master/SUMMARY.md 更新日志: https://github.com/cocos2d/cocos2d-x/blob/v3/CHANGELOG
  • 目前,很多基于cocos2d-x的代码基本仅是对引擎功能的使用,完全不能按照游戏项目的标准来参考。作为游戏项目代码,不仅需要实现游戏的诸多功能,还需要从架构层面,从模块设计的角度来思考和设计,使代码具有更好...
  • 今天发现某些情况下mac模拟器会出现不输出log的情况, 跟踪了一下发现问题出现在mac/SimulatorApp.mm文件的handleNotification方法。 NSString *str = [[[NSString alloc] initWithData:data encoding:NSUTF8...
  • local platform = cc.Application:getInstance():getTargetPlatform()local plats = { WINDOWS = 0, LINUX = 1, MAC = 2, ANDROID = 3, IPHONE = 4, IPAD
  • jni详解介绍JNI是JVM实现中的一部分,因此Native语言和Java代码都运行在JVM的宿主环境。JNI的出现使得开发者既可以利用Java语言跨平台、类库丰 富、开发便捷等特点,又可以利用Native语言的高效。...
  • cocos2d-x打印log

    2016-11-11 10:40:33
    用eclipse进行cocos2d-x开发,以android作为开发平台时。经常需要输出log信息进行调试。当然,网上也有很多的教程,然而我试了几个,发现要不不好用,要不很麻烦。我在这里整理下使用eclipse输出log的方法。 新建一...
  • cocos2dx的自定义log

    2016-03-18 12:01:27
    C++的编译器其实支持了很多预定义的宏: 宏 说明 __DATE__ 当前代码文件的编译日期。格式: Mmm dd yyyy,生成的格式和 ‘’asctime(定义于TIME.H)‘’生成的日期格式一致 ...__
  • 1、__CCLOGWITHFUNCTION 2、CCLOG 3、log 4、printf 5、Android输出 __android_log_print(ANDROID_LOG_ERROR, "Android_Print", "%s", str.c_str());
  • 本文主要介绍新建cocos2dx lua项目,运行新建的cocos2dx lua项目,并且解决一些新建和运行项目过程中可能会遇到的问题。 版本仍然是cocos2dx3.4,本机配置仍然是64位的win7系统。
  • Cocos2d-x之Log输出机制

    2017-10-20 11:15:24
    cocos2d-x中,我们使用log这个函数进行输出,log可以输出很多参数,它的使用方式就和使用c语言中的printf的使用方式差不多。log其实是一个跨平台的日志输出的API,它在visual stdio中,就包含visual stdio的输出...
  • 近日一直被3.0的字体描边所困扰,在安卓手机下字体没问题,挺好看,但是在iphone手机显示特别不清晰,一直很怪异的感觉,尤其是白色的label,后来我同事兼师父将底层改了下,貌似cocos2dx3.2及以后就不存在这个...
1 2 3 4 5 ... 20
收藏数 4,088
精华内容 1,635
关键字:

2dx设备上log cocos