2010-09-07 166 views
1

跟進質詢,我的透水問題: Conditional wait with pthreadssem_wait沒有按預期工作?

我改變了我的代碼使用信號量而不是互斥鎖和條件的信號。但是,我似乎遇到了一個我無法解釋的情況。

這裏是抽象的控制流的

function thread work { 
    while (true) 
    sem_wait(new_work) 
    if (condition to exit){ 
     exit 
     } 
    while (work based condition){ 
     if (condition to exit) 
     exit 
     do work 
     if (condition to exit){ 
     exit 
     } 
    sem_post(work_done) 
    set condition to ready 
    } 
exit 
} 

function start_thread(){ 
sem_wait(work_done) 
setup thread work 
create work 
sem_post(new_work) 
return to main() 
} 

function end_thread(){ 
set condition to exit 
sem_post(new_work) 
pthread_join(thread) 
clean up 
} 

解釋: 主線程調用start_thread了一些工作,創建一個線程,手。主要和工人並行。主要可以在工人之前完成其工作,反之亦然。如果主要在工人面前完成其工作,則工人不再有效,並且必須被告知放棄其工作。這是「退出條件」。這個函數(start_thread)每次調用時都不會創建一個線程,只有第一次。其他時間更新爲線程工作。

線程被重用並提供新的工作參數以減少創建和銷燬線程的開銷。一旦主決定不再需要工作線程,它就調用end_thread函數。這個函數將告訴線程它不再需要,等待它退出,然後清理指針,信號量和工作結構。

線程在開始工作之前會一直等待信號量(new_work)。我正在使用sem new_work來指示新線程現在可用並且應該啓動。線程使用信號量work_done向控制函數(start_thread)發出已完成/中止工作的信號。

除了在一些隨機的情況下,一切都很好。 end_thread正在等待pthread_join並且線程正在等待sem_wait(new_work)。

「退出條件」受互斥鎖保護。

我似乎無法弄清楚是什麼導致了這種情況。

這裏是從跟蹤

thread 1: sem NEW count, before wait : 0 
thread 1: sem NEW count, before wait : 0 
end post: sem NEW count, before post : 0 
end post: sem NEW count, after post : 1 
thread 1 exit. 
thread exited, cleanup 1 

Entered initialization for thread: 2 

created a thread: 2 
thread: 2 started. 

..... 


thread 2: sem NEW count, before wait : 0 
thread 2: sem NEW count, before wait : 0 
thread 2: sem NEW count, before wait : 0 
end post: sem NEW count, before post : 0 
thread 2 exit. 
end post: sem NEW count, after post : 0 
thread exited, cleanup 2 

Entered initialization for thread: 3 

created a thread: 3 
thread: 3 started. 

..... 

thread 3: sem NEW count, before wait : 0 
thread 3: sem NEW count, before wait : 0 
end post: sem NEW count, before post : 0 
end post: sem NEW count, after post : 1 
thread 3: sem NEW count, before wait : 0 

輸出此時,線程在等待信號燈和exit_thread在等待在pthread_join。

謝謝你的時間。

回答

3

sem_t上的POSIX函數可被信號中斷,因此它們被進程/線程可能接收到的任何信號中斷,特別是由於IO。

  • 始終調查的返回值的系統調用 (一般不僅爲 sem_wait
  • 尤其是認沽sem_wait在 while循環,檢查錯誤 條件。如果錯誤情況是 EINTR重新運行sem_wait

同樣適用於其他sem_功能。查看它們的具體錯誤條件並特別處理它們。

0

我發現了這個錯誤。我正在測試互斥鎖外的條件並更改互斥鎖內部條件的值。通過調度的隨機性,可能會發生主線程和工作線程同時競爭鎖並同時改變條件的值。取決於哪個線程最後更改了條件的值,工作線程將在它應該退出時繼續。兩人都在sem_wait等待永遠不會到來的帖子。工作人員等待新工作,而主線程等待工作人員退出,因爲它已經設置退出條件。

我把測試移到了互斥鎖裏面,現在它工作正常。

這裏是修改後的代碼

} 
    sem_post(work_done) 
    enter mutex lock 
    test condition 
     set condition to ready if test is satisfied 
    exit lock 
    } 
的片斷