多線程中避免使用信號量


項目中遇到一個bug,因為接入了幾家越獄平台:91、同步推、PP助手,在設備上安裝了三個應用,啟用其中任意一個,另外二個啟動后無法創建發送socket消息,從而導致游戲直接死在登錄那里,再次點擊登錄時線程才會被喚醒(無法發送的原因定位到,是因為在調用sem_post方法后無法將線程喚醒)。之后我嘗試將信號量改為條件變量,就再也沒有遇到那個問題了。具體改寫的幾個方法:

sem_open/sem_init => pthread_cond_init

sem_close/sem_destroy => pthread_cond_destroy

sem_wait => pthread_cond_wait

sem_post => pthread_cond_signal

 

信號量不僅可以用於進程也可用於線程,它比條件變量要復雜很多,條件變量僅限於線程內使用。

翻看cocos2d-x的源碼中,紋理緩存用到了信號量:

//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

光信號量的初始化就得根據不同平台來寫代碼,而用條件變量進行替代則只需要一行代碼,不需要針對不同的平台寫不同的代碼,代碼量小了。

 

避免使用信號量,除了維護的代碼較多以外,還有一個重要的原因是它容易用錯。陳碩在他的著作《Linux多線程服務端編程》P85頁中明確指出了,避免使用信號量(semaphore),它的功能與條件變量重合,但容易出錯。在《並發編程的 15 條建議(譯)》也提及如果Mutex就能解決問題,就不要使用信號量semaphore。

 

關於使用信號量容易出錯的例子,這里倒有一個:關於sem_open(3),所有信號量這種東東最好不要在線程內使用,進程間通信就要好好去研究它了…

 

附:sem_open的man手冊鏈接>>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM