多線程中避免使用信號量

項目中遇到一個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

 

附:sem_open的man手冊連接>>

相關文章
相關標籤/搜索