项目中遇到一个bug,由于接入了几家越狱平台:9一、同步推、PP助手,在设备上安装了三个应用,启用其中任意一个,另外二个启动后没法建立发送socket消息,从而致使游戏直接死在登陆那里,再次点击登陆时线程才会被唤醒(没法发送的缘由定位到,是由于在调用sem_post方法后没法将线程唤醒)。以后我尝试将信号量改成条件变量,就再也没有遇到那个问题了。具体改写的几个方法:html
sem_open/sem_init => pthread_cond_initios
sem_close/sem_destroy => pthread_cond_destroy编程
sem_wait => pthread_cond_wait缓存
sem_post => pthread_cond_signal多线程
信号量不只能够用于进程也可用于线程,它比条件变量要复杂不少,条件变量仅限于线程内使用。并发
翻看cocos2d-x的源码中,纹理缓存用到了信号量:app
//CCTextureCache.cpp
// lazy init
if (s_pSem == NULL)
{
#if CC_ASYNC_TEXTURE_CACHE_USE_NAMED_SEMAPHORE
s_pSem = sem_open(CC_ASYNC_TEXTURE_CACHE_SEMAPHORE, O_CREAT, 0644, 0);
if( s_pSem == SEM_FAILED )
{
CCLOG( "CCTextureCache async thread semaphore init error: %s\n", strerror( errno ) );
s_pSem = NULL;
return;
}
#else
int semInitRet = sem_init(&s_sem, 0, 0);
if( semInitRet < 0 )
{
CCLOG( "CCTextureCache async thread semaphore init error: %s\n", strerror( errno ) );
return;
}
s_pSem = &s_sem;
#endif
光信号量的初始化就得根据不一样平台来写代码,而用条件变量进行替代则只须要一行代码,不须要针对不一样的平台写不一样的代码,代码量小了。socket
避免使用信号量,除了维护的代码较多之外,还有一个重要的缘由是它容易用错。陈硕在他的著做《Linux多线程服务端编程》P85页中明确指出了,避免使用信号量(semaphore),它的功能与条件变量重合,但容易出错。在《并发编程的 15 条建议(译)》也说起若是Mutex就能解决问题,就不要使用信号量semaphore。async
关于使用信号量容易出错的例子,这里倒有一个:关于sem_open(3),全部信号量这种东东最好不要在线程内使用,进程间通讯就要好好去研究它了…post