2013-08-01 80 views
1
bool flag=false; 
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t cond=PTHREAD_COND_INITIALIZER; 

void function1() 
{ 
    pthread_mutex_lock(&mutex); 
    while(!flag) 
    { 
    //#2 
     pthread_cond_wait(&cond,&mutex); 
    } 
    pthread_mutex_unlock(&mutex); 
} 

void function2() 
{ 
    flag=true; 
    pthread_cond_signal(&cond); 
} 

以下是情況。兩個線程:thread1和thread2分別在function1和function2上運行。pthread_cond_wait()前檢查標誌

由於CPU時間安排,thread1停在#2處。

thread2開始執行並將標誌更改爲true。

thread1開始等待,但它會永遠等待。

如何在不鎖定互斥鎖的情況下通知其他線程的情況下避免這種情況。

+0

你能否詳細說明一下?你的目的不明確 – Saksham

+0

你正在調用未定義的行爲,通過訪問'flag'而沒有同步。 –

回答

4

這就是爲什麼在更新謂詞時必須鎖定互斥鎖(flag)。沒有替代。

pthread_mutex_lock(&mutex); 
flag = true; 
pthread_cond_signal(&cond); 
pthread_mutex_unlock(&mutex); 

(您可以在pthread_mutex_unlock()後移動pthread_cond_signal()如果你想)。

1

caf的回答已經說明了一切,但讓我補充說明爲什麼在這裏需要鎖定的原因,因爲起初這可能有點混亂。

概念上,條件變量信號已達到所需狀態。它本身並不代表該狀態(在你的情況下,狀態代表的是flag變量)。這就是爲什麼您仍需要額外的互斥鎖的原因:對條件變量本身的併發更改受到保護(例如,您可以同時通知多個線程),而保留該狀態的數據更改爲而不是受保護。這就是爲什麼條件變量通常與互斥鎖配對的原因:條件變量表示互斥鎖保護狀態不變。

在某些情況下,您不需要該狀態的互斥體(例如,如果您的標誌是一個原子變量)。當您將無鎖數據結構與條件變量混合時,通常會發生這種情況。這是一種氣味。條件變量用於等待對於特定條件,它們始終是阻塞性的。藉助無鎖數據結構,您可以表達您永遠不想阻止的意圖。混合兩者通常首先表明有缺陷的設計。