2016-10-13 79 views
0

我有兩個線程A和B線程A應該被阻塞,直到從threadB信號,該pthread_cond_signal會似乎並不奏效:pthread_cond_signal會在堆棧變量不工作

struct TR_EVT 
{ 
    Dest* pQDest ; 
    pthread_cond_t evWait ; 
    pthread_mutex_t mutex_tr ; 
}; 

DataSet dSet ; 

threadA() 
{ 
    TR_EVT TrEvt ; 
    dSet->setContext(&TrEvt); 
    pthread_cond_init(&TrEvt.evWait, NULL); 
    . 
    . 
    cout << "Entering Sleep\n" ; 
    pthread_mutex_lock(&TrEvt.mutex_tr); 
    pthread_cond_wait(&TrEvt.evWait, &TrEvt.mutex_tr); 
    pthread_mutex_unlock(&TrEvt.mutex_tr); 
    cout << "Out of Sleep\n" ; 
} 

threadB() 
{ 
. 
. 
    TR_EVT * pTrEvt = NULL ; 
    pTrEvt = (TR_EVT *)dSet->getContext() 
    . 
    . 

    cout << "Signalling...\n" ; 
    pthread_mutex_lock(&(pTrEvt->mutex_tr)); 
    pthread_cond_signal(&(pTrEvt->evWait); //wake up thread A 
    pthread_mutex_unlock(&(pTrEvt->mutex_tr)); 
. 
. 
. 
} 

的ThreadA()永遠不會醒來。可能是什麼問題呢 ?感謝任何幫助

回答

0

Thread B已經發信號通知條件變量後,看來沒有任何東西停止Thread A進入等待狀態。這會產生你描述的症狀。

條件變量必須總是與共享狀態(「謂詞」)上的某些條件配對 - 您不能僅使用裸條件變量。

while (!condition) 
    pthread_cond_wait(...); 

例如:等待的狀態應該然後總是一個循環,檢查這一條件內完成

struct TR_EVT { 
    Dest* pQDest; 
    pthread_cond_t evWait; 
    pthread_mutex_t mutex_tr; 
    int thread_A_can_run; 
}; 

threadA() 
{ 
    TR_EVT TrEvt ; 
    pthread_cond_init(&TrEvt.evWait, NULL); 
    TrEvt.thread_A_can_run = 0; 
    dSet->setContext(&TrEvt); 

    /* ... */ 

    cout << "Entering Sleep\n" ; 
    pthread_mutex_lock(&TrEvt.mutex_tr); 
    while (!TrEvt.thread_A_can_run) 
     pthread_cond_wait(&TrEvt.evWait, &TrEvt.mutex_tr); 
    pthread_mutex_unlock(&TrEvt.mutex_tr); 
    cout << "Out of Sleep\n" ; 
} 

threadB() 
{ 
    TR_EVT * pTrEvt = NULL ; 
    pTrEvt = (TR_EVT *)dSet->getContext() 

    /* ... */ 

    cout << "Signalling...\n" ; 
    pthread_mutex_lock(&(pTrEvt->mutex_tr)); 
    pTrEvt->thread_A_can_run = 1; 
    pthread_cond_signal(&(pTrEvt->evWait); //wake up thread A 
    pthread_mutex_unlock(&(pTrEvt->mutex_tr)); 

    /* ... */ 
} 

這樣,如果線程B到達它想要喚醒點首先,線程A將看到已經設置的條件,而不是等待。互斥量確保這是無競爭的:線程B無法設置線程之間的條件檢查它並等待。

在這裏,我已經添加了條件的一個簡單標誌,但你也許可以使用別的作謂語,而不是(例如,檢查一個指針爲非NULL)。

信令條件變量的目的是要告訴等待線程的條件可能已經改變了,應該重新檢查。

+0

很清楚,非常感謝。 – user1409254