2009-08-03 69 views
2

得到假設我有3個POSIX線程一個C程序,共享的全局變量,互斥鎖,和條件變量,其中兩個是執行以下僞碼:保證與調用pthread_cond_wait和調用pthread_cond_signal

...process data... 
pthread_mutex_lock(&mutex); 
variable = data_ptr; 
pthread_cond_signal(&cond); 
pthread_mutex_unlock(&mutex); 

而第三個運行:

while(1) { 
    while(variable == NULL) { 
     pthread_mutex_wait(&cond, &mutex); 
    } 
    printf("Data is %d", *variable); 
} 

它是安全的假設,第三個線程會看到從每個前兩個數據?

換一種方式,如果一個線程在互斥鎖和條件變量上流水,可以安全地假設它是下一個獲取鎖的信號,而不是其他某個線程在等待鎖?

回答

12

有沒有這樣的事情pthread_mutex_wait。我假設你的意思是:

pthread_mutex_lock(&mutex); 
/* ... */ 
while (1) { 
    while (variable == NULL) 
    pthread_cond_wait(&cond, &mutex); 
    printf("Data is %d", *variable); 
} 
/* ... */ 
pthread_mutex_unlock(&mutex); 

沒有保證第三個線程會看到來自兩者的數據。 pthread_cond_signal會喚醒第三個線程,但它可能不會立即採用該互斥鎖。其他作家之一可能會先接受互斥體。然而,你可以acheive你想要的東西多一點的工作:

void put(int *p) { 
    pthread_mutex_lock(&mutex); 
    while (variable) 
    pthread_cond_wait(&cond_empty, &mutex); 
    variable = p; 
    pthread_cond_signal(&cond_full); 
    pthread_mutex_unlock(&mutex); 
} 

int *get() { 
    int *ret; 

    pthread_mutex_lock(&mutex); 
    while (!variable) 
    pthread_cond_wait(&cond_full, &mutex); 
    ret = variable; 
    variable = NULL; 
    pthread_cond_signal(&cond_empty); 
    pthread_mutex_unlock(&mutex); 

    return ret; 
} 

通過明確等待要讀取的變量,我們避免了潛在的競爭條件。

+0

哎呀,是的,它應該是pthread_cond_wait。 – Edward 2009-08-03 15:20:33

1

以下是我在standard發現:

4.13調度策略

的調度策略影響的進程或線程排序:

[...]

  • 當進程或線程被阻塞的線程並且它變成可運行的線程時

符合實現應該定義每個調度策略可以修改優先級或以其他方式影響上面列出的每個事件的進程或線程的排序的方式。另外,符合實現應該定義在其他情況下以及以何種方式每個調度策略可以修改優先級或影響進程或線程的排序。

所以它顯然是未定義的。這並不奇怪:一般來說,您不能假設任何有關可運行線程將被安排運行的任何信息。

0

按照pthread_cond_wait手冊頁

是暢通應當根據調度策略(如果適用的話),用於互斥抗衡線程(多個),並如同每個都稱爲pthread_mutex_lock()。

不幸的是,據我所知,沒有可用的調度策略給你你想要的行爲。

+2

嚴格地說,單處理器系統上的SCHED_FIFO或SCHED_RR具有比寫入器線程更高的靜態優先級。但是在SMP上,你仍然可以爭奪鎖定。 – bdonlan 2009-08-03 15:15:07

相關問題