天天看點

線程鎖并不是想象的那樣可靠

今天測試時發現程式經常崩潰,代碼大意如下:

static  void  fext_queue(ImageBuffer* pSrc)
{
    //>=0表示初始化完成。
    if (g_FextThreadQueue == NULL
        && g_FextThreadQueue->queue_length < GH_FEXT_QUEUE_LENGTH)
    {
        pthread_mutex_lock(&(g_FextThreadQueue->queue_mutex));
 
     //------------------
 
        g_FextThreadQueue->queue_length ++;
 
        pthread_mutex_unlock(&(g_FextThreadQueue->queue_mutex));
    }
}      

這是怎麼回事?後來把queue_length輸出,發現已經越界了.也就是在加鎖期間,值又變化了.是以正确寫法是:

static  void  fext_queue(ImageBuffer* pSrc)
{
    //>=0表示初始化完成。
    if (g_FextThreadQueue == NULL
        && g_FextThreadQueue->queue_length < GH_FEXT_QUEUE_LENGTH)
    {
        pthread_mutex_lock(&(g_FextThreadQueue->queue_mutex));
 
        //從外界進來的時候,有可能增加了.
        if (g_FextThreadQueue->queue_length >= GH_FEXT_QUEUE_LENGTH)
        {
            g_FextThreadQueue->queue_length = 0;
        }
 
        //-------------------------
 
        g_FextThreadQueue->queue_length ++;
 
        pthread_mutex_unlock(&(g_FextThreadQueue->queue_mutex));
    }
}      

或者這樣寫:

static  void  fext_queue(ImageBuffer* pSrc)
{
    //>=0表示初始化完成。
    if (g_FextThreadQueue == NULL)
    {
        return;
    }
 
    pthread_mutex_lock(&(g_FextThreadQueue->queue_mutex));
 
    if (g_FextThreadQueue->queue_length >= GH_FEXT_QUEUE_LENGTH)
    {
        g_FextThreadQueue->queue_length = 0;
    }
 
    //-------------------------
 
    g_FextThreadQueue->queue_length ++;
 
    pthread_mutex_unlock(&(g_FextThreadQueue->queue_mutex));
}
       

繼續閱讀